正如您所怀疑的,传递成员函数指针是可以接受的做法。
如果你需要知道语法,它是:
int compute_(int a, int b, int (test::*f)(int,int))
{
int c=0;
// Some complex loops {
c += (this->*f)(a,b)
// }
return c;
}
使用整数表示成员函数和切换会引入程序员开销,以便在可用操作列表更改时保持最新状态。所以你不希望这样,除非在特定情况下有一些重要的原因。
一种替代方法是compute
更通用——而不是采用成员函数,而是编写一个采用任何可调用类型的函数模板:
template <typename BinaryFunction>
int compute_(int a, int b, BinaryFunction f) {
// body as before but `f(a,b)` instead of `(this->*f)(a,b)`
}
如果有人想将它与他们自己发明的某个运算符一起使用,这个更通用的模板非常棒,这不是test
. 但是,在成员函数的情况下使用起来更加困难,因为有人需要捕获this
. 有几种方法可以做到这一点 - C++11 lambda boost::bind
, 或写出一个仿函数。例如:
template <typename BinaryFunction>
int compute_(int a, int b, BinaryFunction f) {
// body as before with `f(a,b)`
}
int compute_(int a, int b, int (test::*f)(int,int))
{
return compute_(a, b, bind_this(f, this));
}
定义bind_this
有点麻烦:就像std::bind1st
我们想使用 3-arg 仿函数而bind1st
只使用二元仿函数一样。boost::bind
,并且std::bind
在 C++11 中,更加灵活,并且会处理额外的参数。以下将适用于这种情况,但通常不适用于绑定 2-arg 成员函数:
struct bind_this {
int (test::*f)(int,int);
test *t;
int operator(int a, int b) const {
return (t->*f)(a,b);
}
bind_this(int (test::*f)(int,int), test *t) : f(f), t(t) {}
};
在 C++11 中,您可以只使用 lambda:
int compute_(int a, int b, int (test::*f)(int,int))
{
return compute_(a, b, [=](int c, int d){ return (this->*f)(c,d) });
}