上次分析了使用
mem_fun
和
mem_fun_ref
的原因,但并没有涉及到这两个函数的原理,所以这次打算把它们的源码拿出来看看。
这两个函数都是模板,用来转换某些类的成员函数,使得这些成员函数能够在象
for_each
这样的函数内部调用。
先来看
mem_fun
这个模板函数吧,这个函数一共有四个重载版本:分别为转换带一个参数和不带参数的
const
和非
const
的函数共四个版本,并且按照语法
#3
进行适配。
我们这里只分析转换 "不带参数的成员函数" 的mem_fun函数版本,其他几个版本也都差不多:
//
TEMPLATE FUNCTION 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
template < class _Result, class _Ty > inline
mem_fun_t < _Result, _Ty > mem_fun( _Result (_Ty:: * _Pm)() )
{ // return a mem_fun_t functor adapter
}
这个
mem_fun
函数返回了一个类
mem_fun_t对象,
这个类是仿函数类:
// TEMPLATE CLASS mem_fun_t
template
<class _Result,class _Ty>
class
mem_fun_t: //从unary_function继承而来
public
unary_function<_Ty *, _Result>
{ // functor adapter (*p->*pfunc)(), non-const *pfunc
public
:
//
构造函数,参数为类
_Ty
的一个没有参数的成员函数
explicit mem_fun_t(_Result (_Ty::*_Pm)()): _Pmemfun(_Pm
{// construct from pointer
}
_Result operator()(_Ty *_Pleft) const
{ // call function
return ((_Pleft->*_Pmemfun)());//
按照
#3
调用函数
}
private
:
_Result (_Ty::*_Pmemfun)(); //
保存需要转换的成员函数指针
};
mem_fun_t从unary_function继承,是一个一元仿函数类,它重载了函数调用操作符,并且具有一个参数为类_Ty对象的指针,函数利用这个指针按照方式#3调用类_Ty的成员函数_pmemfun()。仿函数mem_fun_t提供了一般形式的函数调用(#1),满足for_each函数的要求:
list
<
Widget
*>
lpw;
for_each(lpw.begin(), lpw.end(), mem_fun( & Widget::test));
for_each(lpw.begin(), lpw.end(), mem_fun( & Widget::test));
//
OK,mem_fun返回
一个mem_fun_t仿函数,
这句代码可以分解成这样:
mem_fun_t < void ,Widget > mf = mem_fun( & Widget::test);//构造函数对象mf
for_each(lpw.begin(), lpw.end(), mf);
// 可以想象,for_each函数将这样调用我们的仿函数对象mf:
for (; _ChkFirst != _ChkLast; ++ _ChkFirst)
mf( * _ChkFirst); // *_ChkFirst解引后为元素类型Widget *.
//mf重载的调用操作符接受一个widget的指针参数,根据这个指针调用类widget的成员函数test.
接下来分析一下
mem_fun_ref
这个函数,其实它与
mem_fun
函数几乎一样,也都有四个重载本,不同的是,
mem_fun_ref
函数是用来生成按照语法
#2
调用成员函数的仿函数类。
//
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
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_t对象
}
可以看到,
mem_fun_ref
函数返回
mem_fun_ref_t
,而
mem_fun
函数返回
mem_fun_t,
其实这两个返回的类基本相同,只有在调用操作符里面有一点区别,我们来看看。
这是其中一个
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)());//
与
mem_fun_t
主要的不同
//按照语法
#2
调用成员函数
}
private
:
_Result (_Ty::*_Pmemfun)(); // the member function pointer
};
list< Widget> vw;
for_each
(vw.begin(), vw.end(), mem_fun_ref(&Widget::test));
//OK,mem_fun_ref
返
回
mem_fun_ref_t
仿函数
现在,这两个函数模板
mem_fun
和
mem_fun_ref
的原理已经清楚了,它们分别返回相应的仿函数版本来实现一般形式的函数调用
(
语法
#1)
,而仿函数内部完成实际的成员函数调用
.