Essential C++濃縮筆記(三)——泛型編程風格

一、Array如何傳入函數,以及如何被函數返回

傳數組給一個函數,數組類型自動轉換爲指針類型,因而傳的實際是地址。因此下面三種聲明方式的結果是一樣的:

void myFunction(int *param)  {...}        //方式1
void myFunction(int param[3]){...}        //方式2
void myFunction(int param[]) {...}        //方式3

 

二、瞭解泛型指針

定義:(例: vector<string>::iterator iter = svec.begin();

iter被定義爲一個iterator,指向一個vector,後者的元素類型是string,初值指向svec的第一個元素。 

通過iterator取得元素值:提領方式

通過iter調用底部string元素提供的操作,使用arrow運算符(->)

 

三、泛型算法

泛型算法能帶來更大的彈性,而且能減少程序員的負擔, 泛型算法包含很多基本的函數如find(),copy(),sort()等。

摘抄書上附錄的一段話,這段話基本把泛型算法講明白了,其他的主要還是多上手敲代碼。

“算法通常有重載的兩個版本:版本一使用底層元素所屬之類型的內置運算符,包括equality運算符和less-than運算符。版本之二接受function object或者function pointer的傳入,藉此提供和內置運算符不同的行爲。例如,默認情形下,sort()會使用less-than運算符來對容器內的元素排序。如果要改變這一行爲,我們可以傳入預先定義好的greater function object”

sort( vec.begin(), vec.end());
sort( vec.begin(), vec.end(), greater<int>());

 

四、使用Iterator Inserter

使用前要包含iterator頭文件,insertion adapter不能用在Array中。

 

五、使用Iostream Iterator

供輸入及輸出使用的Iostream Iterator類,稱爲istream_iterator和ostream_iterator。

使用前,需要包含iterator頭文件

定義方法:

istream_iterator<string> is(cin);        //定義first iterator
istream_iterator<string> eof;            //不指定istream對象便代表了end-of-file

ostream_iterator<string> os(cout," ");    //定義ostream

//從文件中讀取和寫入,只需要綁定ifstream object對象或ofstream object對象即可
ifstream in_file("input_file.txt";
...
istream_iterator<string> is(in_file);

 

六、程序實現

Task1:對於一個vector,輸入一個數,如果這個數在vector內,返回這個數地址,利用泛型指針將vector擴展到任意容器

#include<iostream>
#include<vector>
#include<string>
#include<iterator>
#include<list>
using namespace std;

int arr[4] = { 1,2,4,5 };
vector<int> vec(arr, arr + 4);

template<typename type, typename Iteratortype>
Iteratortype find(type &num, Iteratortype iter_st, Iteratortype iter_ed);

int main() {		
	vector<int>::iterator iter_st = vec.begin();
	vector<int>::iterator iter_ed = vec.end();
	int num;
	cout << "please input a number:" << endl;
	cin >> num;	
	vector<int>::iterator it;
	it = find(num, iter_st, iter_ed);
	cout << *it << endl;
	
	getchar();
	return 0;
}

//利用泛型指針處理所有容器
template<typename type,typename Iteratortype>
Iteratortype find(type &num, Iteratortype iter_st, Iteratortype iter_ed) {	
	for (; iter_st != iter_ed; iter_st++) {
		if (num == *iter_st)
			return iter_st;
	}
	return iter_ed;
}

 

Task2:使用泛型算法,使得函數能進一步處理任何運算操作(如大於某個值,小於某個值)

#include<iostream>
#include<vector>
#include<string>
#include<iterator>
#include<algorithm>
#include<list>
#include<functional>
using namespace std;

template <typename elemtype>
void show_vec(vector<elemtype> &vec); 
template<typename inputIterator, typename outpuIterator, typename type, typename comp>
outpuIterator filter(inputIterator first, inputIterator last, outpuIterator at, type &val, comp pred);

int ia[8] = { 1,3,6,10,15,21,28,36 };
vector<int> ivec(ia, ia + 8);
list<int> ilist(ia, ia + 8);

string sa[10] = { "the","light","untonsured","hair","grained","and","hued","like","pale","oak" };
vector<string> svec(sa, sa + 10);
list<string> slist(sa, sa + 10);

int main() {
	vector<int> temp(8);
	int val = 10;		
	cout << "array for values less than 10:"<<endl;
	temp.begin() = filter(ivec.begin(), ivec.end(), temp.begin(), val, less<int>());//之前報錯的原因是:沒有輸入一個泛型指針對象 temp.begin()	

	getchar();
	return 0;
}

template <typename inputIterator,typename outpuIterator,typename type,typename comp>
outpuIterator filter(inputIterator first, inputIterator last, outpuIterator at, type &val, comp pred){	
	while ((first = find_if(first, last, bind2nd(pred, val))) != last) {
		cout << "found value: " << *first << endl;			
		*at++ = *first++;		
	}	
	return at;
}

 

七、編程過程遇到的問題&&總結

1、ERROR:“Iterator":類型 從屬名稱的使用必須以“typename”爲前綴

P74頁下面display函數顯示有問題

https://blog.csdn.net/darennet/article/details/40950577

https://blog.csdn.net/weixin_43256707/article/details/103099979

2、間接尋址非法問題

template <typename inputIterator,typename outpuIterator,typename type,typename comp>
outpuIterator filter(inputIterator first, inputIterator last, outpuIterator at, type &val, comp pred) {
	type temp;
	while ((first = find_if(first, last, bind2nd(pred, val))) != last) {
		cout << "found value: " << *first << endl;		
		*at++ = *first++;	
	}	
	return at;
}

有時候如果怎麼修改還是報錯,有可能不是函數定義的問題,有可能是調用的問題。

陷入僵局的時候,最好從頭檢查一次

發佈了31 篇原創文章 · 獲贊 143 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章