- template<class _InIt, class _Fn1>
- _Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)
- {// perform function for each element
- for (; _First != _Last; ++_First)
- _Func(*_First); //Note!
- return (_Func);
- }
用法示例:
- //这是取自MSDN的一个例子
- // The function object to determine the average
- class Average
- {
- private:
- long num; // The number of elements
- long sum; // The sum of the elements
- public:
- // Constructor initializes the value to multiply by
- Average ( ) : num ( 0 ) , sum ( 0 )
- {
- }
- // The function call to process the next elment
- void operator ( ) ( int elem ) \
- {
- num++; // Increment the element count
- sum += elem; // Add the value to the partial sum
- }
- // return Average //默认double类型转换
- operator double ( )
- {
- return static_cast <double> (sum) /
- static_cast <double> (num);
- }
- };
- //这里是调用
- vector <int> v1;
- ...
- double avemod2 = for_each ( v1.begin ( ) , v1.end ( ) , Average ( ) );
- cout << "The average of the elements of v1 is:\n Average ( v1mod2 ) = "
- << avemod2 << "." << endl;
这里函数对象Average将vector v1中的元素累加到自身, 通过for_each返回该函数对象的拷贝, 在将函数对象赋值给double类型变量avemod2的时候调用自定义默认类型转换运算符函数operator double(), 该函数通过自身累加数据返回平均值。通过这个例子我们可以感受到for_each结合函数对象的神奇妙用。
函数对象的构造
STL有一些函数可以用来专门构造特定的函数对象, 这些函数定义在<functional> <xfunctional>里面,常用的如:
ptr_fun 可以将C式函数转换为函数对象pointer_to_unary_funciton, pointer_to_binary_function, 这些函数对象的operator()接受参数和原函数相同
mem_fun, mem_fun1可以将C++类成员函数转换为函数对象mem_fun_t, mem_fun1_t。这些函数对象的operator() 接受类对象的指针, 所以传递给for_each的时候要注意容器中的元素应为对象指针。
mem_fun_ref, mem_fun1_ref 可以将C++类成员函数转换为函数对象mem_fun_ref_t, mem_fun1_ref_t。这俩函数功能与上面两个相同,只是这些函数对象的operator() 接受类对象的ref。
由于for_each接受的函数对象要求operator()只接受一个参数, STL还提供了2个很常用的函数:bind1st, bind2nd, 将双参数的函数对象的其中一个参数和一个变量或值关联起来, 返回一个只接受一个参数的函数对象。
以上提到函数详情请查阅MSDN和STL源码, 下面再贴一个例子, 依然取自MSDN:
- // functional_mem_fun.cpp
- // compile with: /EHsc
- #include <vector>
- #include <functional>
- #include <algorithm>
- #include <iostream>
- using namespace std;
- class StoreVals
- {
- int val;
- public:
- StoreVals() { val = 0; }
- StoreVals(int j) { val = j; }
- bool display() { cout << val << " "; return true; }
- int squareval() { val *= val; return val; }
- int lessconst(int k) {val -= k; return val; }
- };
- int main( )
- {
- vector<StoreVals *> v1;
- StoreVals sv1(5);
- v1.push_back(&sv1);
- StoreVals sv2(10);
- v1.push_back(&sv2);
- StoreVals sv3(15);
- v1.push_back(&sv3);
- StoreVals sv4(20);
- v1.push_back(&sv4);
- StoreVals sv5(25);
- v1.push_back(&sv5);
- cout << "The original values stored are: " ;
- for_each(v1.begin(), v1.end(), mem_fun<bool, StoreVals>(&StoreVals::display));
- cout << endl;
- // Use of mem_fun calling member function through a pointer
- // square each value in the vector using squareval ()
- for_each(v1.begin(), v1.end(), mem_fun<int, StoreVals>(&StoreVals::squareval));
- cout << "The squared values are: " ;
- for_each(v1.begin(), v1.end(), mem_fun<bool, StoreVals>(&StoreVals::display));
- cout << endl;
- // Use of mem_fun1 calling member function through a pointer
- // subtract 5 from each value in the vector using lessconst ()
- for_each(v1.begin(), v1.end(), bind2nd (mem_fun1<int, StoreVals,int>(&StoreVals::lessconst), 5));
- cout << "The squared values less 5 are: " ;
- for_each(v1.begin(), v1.end(), mem_fun<bool, StoreVals>(&StoreVals::display));
- cout << endl;
- }
最后一点:
for_each调用函数对象的operator()的时候并不关注operator()的返回值, STL还有其他一些函数实现类似于for_each。根据operator() 的返回值在遍历的时候实现更多的功能。如count_if, find_if等等。