天天看點

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 正确調用方式
在這裡插入代碼片
           

繼續閱讀