for_each详解

12 篇文章 0 订阅
说明:在使用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

 */



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值