使用成员函数的算法
有许多算法都是将某个函数应用于一个序列里的各个元素。例如,在3.8.4节
for_each(ii, eos, record);
对输入的每个串调用 record()
。
我们也经常需要处理指针的容器,而且实际希望的是对每个被指向的元素调用它的某个成员函数,而不是对指针去使用一个全局函数。例如,我们可能想对一个 list<Shape*>
里的每个元素调用成员函数 Shape::draw()
。要处理这个特定例子,我们先简单写出一个非成员函数,让它去调用成员函数。例如,
void draw(Shape* p)
{
p->draw();
}
void f(list<Shape*>& sh)
{
for_each(sh.begin(), sh.end(), draw);
}
通过将这种技术加以推广,我们就可以按如下方式写出这个例子:
void g(list<Shape*>& sh)
{
for_each(sh.begin(), sh.end(), mem_fun(&Shape::draw)); // #include <functional>
}
标准库模版 mem_fun()
(18.4.4.2节)以一个到成员函数的指针(15.5节)为参数,产生出某种东西,使它可以对某个指向该成员所在的类的指针调用。这里 mem_fun(&Shape::draw)
的结果就以 Shape*
为参数,返回的就是 Shape::draw()
返回的东西。
这种 mem_fun()
机制是非常重要的,因为它使各种标准算法能够被应用于保存多态对象的容器。
注(edit by shenjun):
#include <iostream>
#include <string>
#include <typeinfo>
using namespace std;
class Foo
{
public:
void foo(int a)
{ cout << a << endl; }
static void bar(int a)
{ cout << a << endl; }
};
int main(int argc, const char *argv[])
{
//veersion 1
//void (*pFunc)(int) = &Foo::foo; //错误 ❌
//Foo::foo 的形式参数有两个:一个隐式,一个int
//void (*pFunc)(int)的形式参数只有一个
// pFunc(123);
//version 2
void (*pFunc)(int) = &Foo::bar;//ok
pFunc(123);
//这里表明:static成员函数的参数没有隐式参数(本对象)
//修正1-->为其加一个参数即可
void (Foo::*pFunc2)(int) = &Foo::foo;
Foo f;
(f.*pFunc2)(12345);
Foo *pf = &f ;
(pf->*pFunc2)(123124);
return 0;
}
mem_fun适配器:
头文件:<functional>
既然 foo
含有一个隐式参数,那么能否将其转化出来呢?我们使用STL中的 mem_fun
,这是一种函数适配器。
Foo f;
//void (Foo::*)(int)->void (*)(Foo*,int)
(mem_fun(&Foo::foo))(&f,123);
mem_fun
的具体作用是一种转化作用,将 void (Foo::)(int)
类型的成员函数指针转化为 void (Foo, int)
,后者是一个自由函数类型的指针,可以像 static
成员函数那样自由调用。
🔚