说明:在使用STL算法库的过程中,如果单单就某个函数做一些使用,而不了解其内部的实现原理,在使用过程中将会存在大量的"问题",因此,在最近这段时间里,我将对每个函数深入挖掘 定义(vs2010 stl版本) 函数功能:对区间[beg,end)执行_Fn1.并返回_Fn1. template<class _InIt, class_Fn1> inline _Fn1 _For_each(_InIt _First, _InIt_Last, _Fn1 _Func) { // perform function for each element for (;_First != _Last; ++_First) _Func(*_First); return(_Func); } template<class _InIt, class_Fn1> inline _Fn1 for_each(_InIt _First, //start interval _InIt _Last, //endinterval,即[_First,_Last) _Fn1_Func) //function object or function(unary_function) { // perform function for each element _DEBUG_RANGE(_First, _Last); _DEBUG_POINTER(_Func); return(_For_each(_Unchecked(_First), _Unchecked(_Last), _Func)); } 注意:for_each返回仿函数(即当时传递进去的仿函数),不过状态可能改变了. 有了这个函数的定义,使用就简单了. template<typenameT> class OperatorValue { private: T _value; public: OperatorValue( T value ):_value( value){} void operator()( T element ) { cout<<element<<" "; _value += element; } T returnValue() { return_value; } }; int main() { vector<int>vecInt; vecInt.push_back( 2 ); vecInt.push_back( 5 ); vecInt.push_back( 7 ); vecInt.push_back( 3 ); OperatorValue<int> val = for_each(vecInt.begin(),vecInt.end(),OperatorValue<int>(0 )); cout<<"\n"<<val.returnValue(); system( "pause"); return0; } 需要说明的是: 1) 可以在operator()中使用引用参数,这样就可以修改元素的值.但这种方法并不可取.如果需要修改元素的值,你应该使用transform. 2) for_each的返回值之所以有用,完全是因为它是仿函数而给一般的函数(前者有状态,而后者没有). 3) 在函数的使用过程中仿函数的状态时改变的.但这种改变对for_each操作不产生”异常”(关于这一点,请参看我的另一篇博客:点击打开链接)
#include <iostream> #include <vector> #include <deque> #include <list> #include <set> #include <map> #include <string> #include <algorithm> #include <iterator> #include <functional> #include <numeric> /* PRINT_ELEMENTS() * - prints optional C-string optcstr followed by * - all elements of the collection coll * - separated by spaces */ template <class T> inline void PRINT_ELEMENTS (const T& coll, const char* optcstr="") { typename T::const_iterator pos; std::cout << optcstr; for (pos=coll.begin(); pos!=coll.end(); ++pos) { std::cout << *pos << ' '; } std::cout << std::endl; } /* INSERT_ELEMENTS (collection, first, last) * - fill values from first to last into the collection * - NOTE: NO half-open range */ template <class T> inline void INSERT_ELEMENTS (T& coll, int first, int last) { for (int i=first; i<=last; ++i) { coll.insert(coll.end(),i); } } using namespace std; // function object to process the mean value class MeanValue { private: long num; // number of elements long sum; // sum of all element values public: // constructor MeanValue () : num(0), sum(0) { } // function call // - process one more element of the sequence void operator() (int elem) { num++; // increment count sum += elem; // add value } // return mean value (implicit type conversion) 注意重载的写法 operator double() { return static_cast<double>(sum) / static_cast<double>(num); } }; int main() { vector<int> coll; INSERT_ELEMENTS(coll,1,8); // process and print mean value 返回值本来是MeanValue,转化为double,需要重载double double mv = for_each (coll.begin(), coll.end(), // range MeanValue()); // operation cout << "mean value: " << mv << endl; } /* mean value: 4.5 */
for_each详解
最新推荐文章于 2022-06-29 18:25:50 发布