for_each各種情況下的函式物件使用方法
原創作者:http://oomusou.cnblogs.com
Introduction
學習過STL的container後,想要存取每一個iterator,你一定寫過以下的程式
#include <vector>
#include <iostream>
usingnamespace std;
int main() {
int ia[] = {1, 2, 3};
vector<int> ivec(ia, ia + sizeof(ia) / sizeof(int));
for(vector<
cout << *iter << endl;
}
}
執行結果
1
2
3
當時我覺得STL什麼都好,就是以下這一串又臭又長
for(vector<int>::const_iterator iter = ivec.begin(); iter != ivec.end(); ++iter) {
若不常寫,一時還會寫不出來,其實若配合container,C++其實不應該這樣像寫迴圈,正確的方式該使用for_each(),語法會變得相當簡單。
for_each()事實上是個function template,其實做如下[effective STL item 41]
template<typename InputIterator, typename Function>
Function for_each(InputIterator beg, InputIterator end, Function f) {
while(beg != end)
f(*beg++);
}
由以上source可知,for_each()只能配合global function和function object。
以下我們將對procedure based(基於程式)、object oriented(面向物件)、generics(通用)三種paradigm與for_each()搭配做探討。
ProcedureBased與for_each()搭配
1.不傳入引數
1 /*
2(C) OOMusou 2007 http://oomusou.cnblogs.com
3Filename : GenericAlgo_for_each_GlobalFunction.cpp
4Compiler : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
5Description : Demo how to use for_each with global function
6Release : 05/11/2007 1.0
7*/
8#include <iostream>
9#include <vector>
10#include <iostream>
11#include <algorithm>
12
13usingnamespace std;
14
15void printElem(int& elem) {
16 cout << elem << endl;
17}
18
19int main() {
20int ia[] = {1, 2, 3};
21 vector<int> ivec(ia, ia + sizeof(ia) / sizeof(int));
22
23 for_each(ivec.begin(), ivec.end(), printElem);
24}
執行結果
1
2
3
只需將vector::begin(),vector::end()和global function name傳給for_each()即可,再也不用for迴圈那種複雜的語法了。
2.傳入引數
若要傳引數給global function,就不能再只傳global function name而已,必須透過ptr_fun()這個function adapter將global function轉成function object,然後再用bind2nd()將引數bind成一個functionobject。
8#include <iostream>
9#include <vector>
10#include <iostream>
11#include <algorithm>
12#include <functional>
13
14usingnamespace std;
16void printElem(int elem, constchar* prefix) {
17 cout << prefix << elem << endl;
18}
19int main() {
21int ia[] = {1, 2, 3};
22 vector<int> ivec(ia, ia + sizeof(ia) / sizeof(int));
23
24 for_each(ivec.begin(), ivec.end(), bind2nd(ptr_fun(printElem), "Element:"));
25}
ptr_fun輔助構造一般函式指標的point_to_binary_function或是
pointer_to_unary_function介面卡例項
構造一元函式指標適配申明如下:
template<typename Arg, typename Result>
pointer_to_unary_function<Arg, Result, Result (*)(Arg)> ptr_fun(Result (*_pfunc)(Arg));
首先,STL定義了binder2nd類,該類繼承自unary_function,在類的函式運算體中完成對二元函式的引數傳遞和呼叫。binder2nd的例項構造通常比較冗長,bind2nd函式用於輔助構造binder2nd的一個例項(返回一個binder2nd類的物件,這個類應該過載了()運算子)。
bind2nd的原型宣告為:
template<typename Operation, typename Type>
binder2nd<Operation> bind2nd(
const Operation& _Func,
const Type& _Right
);
binder2nd函式詳解
執行結果
Element:1
Element:2
Element:3
ObjectOriented與for_each()搭配
1.不傳入引數
使用function object
1 /*
2(C) OOMusou 2007 http://oomusou.cnblogs.com
3Filename : GenericAlgo_for_each_FunctionObject.cpp
4Compiler : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
5Description : Demo how to use for_each with function object
6Release : 05/11/2007 1.0
7*/
8#include <iostream>
9#include <vector>
10#include <iostream>
11#include <algorithm>
12
13usingnamespace std;
14
15struct printElem {
16voidoperator() (int elem) {
17 cout << elem << endl;
18 }
19};
20
21int main() {
22int ia[] = {1, 2, 3};
23 vector<int> ivec(ia, ia + sizeof(ia) / sizeof(int));
24
25 for_each(ivec.begin(), ivec.end(), printElem());//傳入一個物件
26}
執行結果
1
2
3
2.傳入引數
若使用function object,也可以將引數傳給printElem(),通過constructor的技巧接收引數。
1 /*
2(C) OOMusou 2007 http://oomusou.cnblogs.com
3Filename : GenericAlgo_for_each_FunctionObjectWithParameter.cpp
4Compiler : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++
5Description : Demo how to use for_each with function object with parameter
6Release : 05/11/2007 1.0
7*/
8#include <iostream>
9#include <vector>
10#include <iostream>
11#include <algorithm>
12
13usingnamespace std;
14
15struct printElem {
16constchar* _prefix;
17
18 printElem(constchar* prefix) : _prefix(prefix) {}
19
20voidoperator() (int elem) {
21 cout << _prefix << elem << endl;
22 }
23};
24
25int main() {
26int ia[] = {1, 2, 3};
27 vector<int> ivec(ia, ia + sizeof(ia) / sizeof