Essential C++濃縮ノート(三)-汎用プログラミングスタイル

5231 ワード

一、Arrayがどのように関数を入力し、どのように関数に返されるか
配列は関数に渡され、配列タイプは自動的にポインタタイプに変換されるので、実際にはアドレスが渡されます.次の3つの宣言の結果は同じです.
void myFunction(int *param)  {...}        //  1
void myFunction(int param[3]){...}        //  2
void myFunction(int param[]) {...}        //  3

 
二、汎用ポインタの理解
定義:(例:vector::iterator iter=svec.begin();
iterはiteratorとして定義され、vectorを指し、後者の要素タイプはstringであり、初期値はsvecの最初の要素を指す. 
iteratorによる要素値の取得:抽出方式
下部string要素が提供するアクションをiterで呼び出し、arrow演算子(->)を使用します.
 
三、汎用アルゴリズム
汎用アルゴリズムはより大きな弾力性をもたらし,プログラマーの負担を減らすことができ,汎用アルゴリズムにはfind(),copy(),sort()などの多くの基本的な関数が含まれている.
本の付録の一節を抜粋して、この話は基本的に汎用アルゴリズムを理解して、その他の主なのはやはり多くコードを叩くことです.
「アルゴリズムには通常、リロードされる2つのバージョンがあります.バージョン1では、equality演算子とless-than演算子を含む最下位要素が属するタイプの組み込み演算子が使用されます.バージョン2ではfunction objectまたはfunction pointerの入力が受け入れられ、組み込み演算子とは異なる動作が提供されます.たとえば、デフォルトではsort()less-than演算子を使用して、コンテナ内の要素をソートします.この動作を変更するには、あらかじめ定義されたgreater function objectに転送できます.
sort( vec.begin(), vec.end());
sort( vec.begin(), vec.end(), greater());

 
四、Iterator Inserterの使用
使用する前にiteratorヘッダファイルを含める必要があります.insertion adapterはArrayでは使用できません.
 
五、Iostream Iteratorの使用
入力および出力用のIostream Iteratorクラス、istream_iteratorとostream_iterator.
使用前にiteratorヘッダファイルを含める必要があります
定義方法:
istream_iterator is(cin);        //  first iterator
istream_iterator eof;            //   istream      end-of-file

ostream_iterator os(cout," ");    //  ostream

//         ,     ifstream object   ofstream object    
ifstream in_file("input_file.txt";
...
istream_iterator is(in_file);

 
六、プログラム実現
Task 1:1つのvectorに対して、1つの数を入力し、もしこの数がvector内にあるならば、この数のアドレスを返して、汎用ポインタを利用してvectorを任意の容器に拡張します
#include
#include
#include
#include
#include
using namespace std;

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

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

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

//            
template
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;
}

 
Task 2:汎用アルゴリズムを使用して、関数が任意の演算操作(例えば、ある値より大きく、ある値より小さい)をさらに処理できるようにする.
#include
#include
#include
#include
#include
#include
#include
using namespace std;

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

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

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

int main() {
	vector temp(8);
	int val = 10;		
	cout << "array for values less than 10:"<());//        :             temp.begin()	

	getchar();
	return 0;
}

template 
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」を接頭辞としなければならない
P 74ページ下のdisplay関数に問題が表示されます
https://blog.csdn.net/darennet/article/details/40950577
https://blog.csdn.net/weixin_43256707/article/details/103099979
2、間接アドレス不正問題
template 
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;
}

どのように修正するか、エラーを報告するかは、関数定義の問題ではなく、呼び出しの問題である可能性があります.
行き詰まったときは、最初からチェックしたほうがいいです.