STL中的for_each调用类成员函数,mem_fun, mem_fun_ref用法

先看一个STL中for_each的用法

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <iterator>
using namespace std;
class Test
{
public:
	Test(int _data = 0):data(_data){}
	
	void print(){cout<<"i am class Test"<< data<<endl;}
	void add(int b){ data += b;}
	int data;
};

int val[] = {0,1,2,3,4,5,6};
int main()
{	Test t(3);
	vector<int> ivec(val,val+7);
	vector<Test> tvec;
	copy(istream_iterator<int>(cin),istream_iterator<int>(),back_inserter(tvec));
	/*这个地方是将int隐式转化为Test类型了,与本主题无关,使用ctrl+z结束输入*/
	for_each(tvec.begin(),tvec.end(),Test::print);
	for_each(ivec.begin(),ivec.end(),t.add);
}


我们的目的很明显,

1.输出vector<Test>的所有变量 ,, 通过调用成员变量print函数

2.将ivec中的七个数加上类变量t中,使用t.add(int)函数.

但是上面的1,2两句确怎么也无法成功...   (当然了可以用for循环来做,,但这就违背了Template的初忠了)

下面讲解下方法:

1.对于

	for_each(tvec.begin(),tvec.end(),&Test::print);
这里要引出mem_fun或者mem_fun_ref这个函数适配器了. 正确的写法:

for_each(tvec.begin(),tvec.end(),mem_fun_ref(&Test::print));
这样就能成功达到我们的第一个目的了.

分析下mem_fun_ref这个东西 可以看下源码

		// TEMPLATE FUNCTION mem_fun_ref
template<class _Result,
	class _Ty> inline
	mem_fun_ref_t<_Result, _Ty> mem_fun_ref(_Result (_Ty::*_Pm)())
	{	// return a mem_fun_ref_t functor adapter
	return (std::mem_fun_ref_t<_Result, _Ty>(_Pm));
	}


mem_fun_ref准确的说是个函数,他返回的是mem_fun_ref_t类. 

函数的声明为:

template<class _Result, class _Ty>
inline mem_fun_ref_t<_Result,_Ty> mem_fun_ref(_Result (_Ty::*_Pm)());
mem_fun_ref函数的形参是一个类成员函数指针为   _Result (_Ty::*_Pm)()    ,  注意最右边的空() ,  这个函数指针无参数,,  类为_Ty ,  类成员函数指针为_Pm,  成员函数返回值为_Result

故拿这个来说明下:

mem_fun_ref(&Test::print)

这句将返回一个mem_fun_ref_t的类 , 其中:

_Result  为Test::print的返回值  , ,, 即  void

_Ty 为Test::print的类    ,, ,, , ,, 即    Test

_Pm为类成员函数指针 , 即  &print

然后再看下class mem_fun_ref_t的定义

		// TEMPLATE CLASS mem_fun_ref_t
template<class _Result,
	class _Ty>
	class mem_fun_ref_t
		: public unary_function<_Ty, _Result>
	{	// functor adapter (*left.*pfunc)(), non-const *pfunc
public:
	explicit mem_fun_ref_t(_Result (_Ty::*_Pm)())
		: _Pmemfun(_Pm)
		{	// construct from pointer
		}

	_Result operator()(_Ty& _Left) const//重要的是这一句,,注意了!
		{	// call function
		return ((_Left.*_Pmemfun)());
		}

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


模板类mem_fun_ref_t中前面已经分析了对于
mem_fun_ref(&Test::print)
来说_Result  = void  , _Ty = Test .   构造函数将_Pmemfun指针指向 &Test::print成员函数

该类重载了operator() 故为仿函数(functor) ,
对于最前面的for_each ,  第三个实参为函数指针_pfn , , 

for_each内部会这样调用 _pfn( Test)

那么应用到这里,即

_Result operator()(_Ty &_Left)const

{return ((_Left.*_Pmemfun)());} 

每次传给这个仿函数一个functor, ,然后成为变量_Left , 调用 _Left.print  就达到了目的( 对tvec里面的每一个Test类变量 ,  都调用自身的print成员函数.


ps: 至于mem_fun这个的用法,差不多 

当对于vector<Test*> ptvec;时 , 就得用mem_fun ,,,可以自已分析下源码


2.mem_fun1_ref,

上述例子中的第二个for_each解决方案, 就得使用me_fun1_ref 这个会返回带一个参数的funtor(仿函数)  , 具体分析待续

.....



3.修改后的程序为

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <iterator>
using namespace std;
class Test
{
public:
	Test(int _data = 0):data(_data){}

	void print(){cout<<"i am class Test"<< data<<endl;}
	void add(int b){ data += b;}
	int data;
};

int val[] = {0,1,2,3,4,5,6};
int main()
{	Test t(3);
	vector<int> ivec(val,val+7);
	vector<Test> tvec;
	copy(istream_iterator<int>(cin),istream_iterator<int>(),back_inserter(tvec));//这个地方是将int隐式转化为Test类型了,与本主题无关
	for_each(tvec.begin(),tvec.end(),mem_fun_ref(&Test::print));
	for_each(ivec.begin(),ivec.end(),bind1st(mem_fun1_ref(&Test::add),t)); //此句在vs2008上通不过,,别的IDE,codeblock上面没mem_fun1_ref这个东西,,看vs2010行不行了
}


发布了53 篇原创文章 · 获赞 12 · 访问量 50万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章