当前位置: 首页 > 工具软件 > Funf > 使用案例 >

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

林俊晖
2023-12-01

如果有一个函数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

std::for_each(datas.begin(), datas.end(), Test); // 调用方式1

假设Test是Widget的成员函数:

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

也应该可以使用for_each在datas中的每个对象上调用Widget::Test():

std::for_each(datas.begin(), datas.end(), &Widget::Test); // 调用方式2

如果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_ref和mem_funmem_func用来指针类型上,其他的使用mem_func_refmem_funmem_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 正确调用方式
在这里插入代码片
 类似资料: