关于for_each,mem_fun和bind1st在类内部组合使用的心得

关于for_each,mem_funbind1st在类中的组合使用

 

考虑有这样的情况,在一个类中有一个容器保存了一些值,现在要遍历这些值并将其作为参数调用这个类的某个成员函数。我们除了直接遍历调用外,也可以用for_each的方法调用,这里介绍了在类内部成员容器遍历调用类内部成员函数的方法。

 

比如有一个vector容器:

    std::vector<int> vct;

你可以用for加迭代器的方式来遍历调用,

     for(std::vector<int>::iterator itr = vct.begin();

         itr != vct.end();++itr)

         func(*itr);

 

 

如果这个func是全局函数的话,我们还可以用stlfor_each泛型算法来调用

std::for_each(vct.begin(),vct.end(),&func);

 

但是如果这个func是类成员函数,我们这样写就会有问题。

正确的做法是:对于这个for_each中的第3个函数指针参数,我们可以这样写

std::bind1st(std::mem_fun(&Class::func), this);

看一下这个函数调用做了什么处理,首先查看mem_fun的源码

template<class _Result,

     class _Ty> inline

     mem_fun_t<_Result, _Ty> mem_fun(_Result (_Ty::*_Pm)())

     {    // return a mem_fun_t functor adapter

     return (mem_fun_t<_Result, _Ty>(_Pm));

     }

 

mem_fun有一个参数也就是我们传入的类成员函数指针,这个函数调用mem_fun_t这个函数,继续看stlmem_fun_t源码

         // TEMPLATE CLASS mem_fun_t

template<class _Result,

     class _Ty>

     class mem_fun_t

         : public unary_function<_Ty *, _Result>

     {    // functor adapter (*p->*pfunc)(), non-const *pfunc

public:

     explicit mem_fun_t(_Result (_Ty::*_Pm)())

         : _Pmemfun(_Pm)

         {    // construct from pointer

         }

 

     _Result operator()(_Ty *_Pleft) const

         {    // call function

         return ((_Pleft->*_Pmemfun)());

          }

 

private:

     _Result (_Ty::*_Pmemfun)(); // the member function pointer

     };

 

这个实际上是定义了一个mem_fun_t类,并将我们mem_fun参数里所传入的函数指针保存在私有成员变量_Pmemfun中。这个类重载了()运算符。在这个重载运算符的函数体中,调用_Pleft参数指针指向的成员函数,也就是_Pmemfun指向的成员函数完成了成员函数的调用过程。

看完了mem_fun,我们再看下std::bind1st的功能。这个函数的功能是将第2个参数作为第一个函数指针参数的第一个值来使用。我们这里调用的是

std::bind1st(std::mem_fun(&Class::func), this);

还记得刚才说的mem_fun_t()重载运算符吗?这个重载函数的参数也就是我们传入的this,通过bind1st,我们将this指针手动绑定到mem_fun的第一个参数中,完成了函数的功能。

这里是完整的测试代码

#include <vector>

#include <iostream>

#include <algorithm>

 

class Test

{

     typedef std::vector<int> INT_VCT;

public:

     Test()

     {

         int a[3] = {1,2,3};

         vct = INT_VCT(a,a+3);

     }

 

     void print(int a)

     {

         std::cout << a << std::endl;

     }

 

     void printAll()

     {

         std::for_each(vct.begin(),vct.end(),std::bind1st(std::mem_fun(&Test::print), this));

     }

 

private:

     INT_VCT vct;

};

 

int main()

{

     Test test;

     test.printAll();

     return 0;

}

 

对于类成员函数指针有疑惑的地方可以参看我之前的博文:

 

使用类成员函数指针调用C++成员函数的一种方式

http://blog.csdn.net/duboleon/archive/2010/09/12/5878483.aspx

你可能感兴趣的:(关于for_each,mem_fun和bind1st在类内部组合使用的心得)