您的位置:首页 > Web前端

effective stl 第41条:理解ptr_fun/mem_fun/mem_fun_ref的由来

2016-10-05 11:42 393 查看
这三个函数的主要作用是掩盖C++语言中一个内在的语法不一致的问题。

#include<iostream>
#include<vector>
#include<list>
#include<algorithm>

using namespace std;

class Widgets
{
public:
Widgets(){};
void test(){};
private:

};

//假设是一个可以测试widgets的对象
void test(const Widgets& w)
{

}

int main()
{
//存放widget的容器
vector<Widgets> vW;
//测试vW中的每一个 Widget对象
for_each(vW.begin(), vW.end(), test);//#1,可以通过编译
//假设test是Widget的成员对象
for_each(vW.begin(), vW.end(), &Widgets::test);//#2,不能通过编译
list<Widgets*> lpw;
for_each(lpw.begin(), lpw.end(), &Widgets::test);//#3,不能通过编译
return 0;
}


通过查看STL想用的源代码,我们发现,我们只有一个for_each的算法。

// TEMPLATE FUNCTION for_each
template<class _InIt,
class _Fn1> inline
void _For_each(_InIt _First, _InIt _Last, _Fn1& _Func)
{   // perform function for each element
for (; _First != _Last; ++_First)
_Func(*_First);
}

template<class _InIt,
class _Fn1> inline
_Fn1 for_each(_InIt _First, _InIt _Last, _Fn1 _Func)
{   // perform function for each element
_DEBUG_RANGE(_First, _Last);
_DEBUG_POINTER(_Func);
_For_each(_Unchecked(_First), _Unchecked(_Last), _Func);

return (_STD move(_Func));
}


上边的代码很明显的表示for_each的实现是基于使用语法#1的。这是STL中一个很普遍的惯例:函数或者函数对象在被调用时,总是使用非成员函数的语法形式。

现在mem_fun和mem_fun_ref之所以必须存在的原因已经很清楚了——他们被用来调整成员函数,使之能通过语法#1被调用。

#include<iostream>
#include<vector>
#include<list>
#include<algorithm>
#include<functional>

using namespace std;

class Widgets
{
public:
Widgets(){};
void test(){};//执行自测,如果不通过,则将*this标记为失败
private:

};

//假设是一个可以测试widgets的对象
void test(const Widgets& w)
{

}

int main()
{
//存放widget的容器
vector<Widgets> vW;
//测试vW中的每一个 Widgets对象
for_each(vW.begin(), vW.end(), test);//#1,可以通过编译
//假设test是Widgets的成员对象
for_each(vW.begin(), vW.end(), mem_fun_ref(&Widgets::test));//#2,不能通过编译
list<Widgets*> lpw;
for_each(lpw.begin(), lpw.end(), mem_fun(&Widgets::test));//#3,不能通过编译
return 0;
}


如果你不知道什么时候使用ptr_fun,什么时候不使用ptr_fun,那么你可以每次将一个函数传给一个STL的组件时总是使用它。stl不会在意,而且这样做不会带来性能的损失。另一种策略是,只有在迫不得已的时候使用,如果你省略了那些必要的类型定义,编译器会提醒你。然后再把ptr_fun加上去。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: