天天看点

41. 理解ptr_fun、mem_fun和mem_fun_ref的来由

如果有一个函数f和一个对象x,现在希望在x上调用f,而我们在x的成员函数之外,执行这个调用,C++提供了三种方法:

  • f(x); // 语法1 f是一个非成员函数
  • x.f();// 语法2 f时成员函数,x是一个对象或对象的引用
  • p->f(); // 语法3 f是成员函数,p是一个对象指针

有一个用于测试Widget对象的函数Test和一个存放Widget的容器datas:

void Test(Widget& w);
std::vector<Widget> datas;
           

为了测试datas中的每一个对象,可以使用如下方式来调用

for_each

假设Test是Widget的成员函数:

class Widget
{
public:
	...
	void Test();
	...
}
           

也应该可以使用

for_each

在datas中的每个对象上调用Widget::Test():

如果datas中保存的是Widget*指针,也应该可以使用for_each来调用Widget::Test():

std::vector<Widget*> datas;
std::for_each(datas.begin(), datas.end(), &Widget::Test); // 调用方式3
在这里插入代码片
           

实际情况是:调用方式1成功,调用方式2、调用方式3都失败。

先看下

for_each

算法的实现:

template<typename InputInterator, typename Function>
Function for_each(InputIterator begin, InputIterator end, Function f)
{
	while (begin != end) f(*begin++);
}
           

调用1完成符合

for_each

内部的调用方式。调用方式2、调用方式3都不符合。

那调用方式2、调用方式3如何修改?

分别使用

mem_fun_re

f和

mem_fun

mem_func

用来指针类型上,其他的使用

mem_func_ref

mem_fun

mem_func_ref

内部可以将调用方式2、调用方式3都转换成调用方式1,内部涉及到函数对象配接器。

std::vector<Widget> datas;
std::for_each(datas.begin(), datas.end(), mem_func_ref(&Widget::Test)); // 调用方式2 正确调用方式
           

如果datas中保存的是Widget*指针,也应该可以使用for_each来调用Widget::Test():

std::vector<Widget*> datas;
std::for_each(datas.begin(), datas.end(), mem_func(&Widget::Test)); // 调用方式3 正确调用方式
在这里插入代码片
           

继续阅读