ご想像のとおり、メンバー関数ポインターを渡すことは許容される方法です。
構文を知る必要がある場合は、次のとおりです。
int compute_(int a, int b, int (test::*f)(int,int))
{
int c=0;
// Some complex loops {
c += (this->*f)(a,b)
// }
return c;
}
整数を使用してメンバー関数を表し、切り替えを行うと、使用可能な操作のリストが変更されたときに最新の状態に保つためのプログラマーのオーバーヘッドが発生します。したがって、特定のケースで重要な理由がない限り、それは望ましくありません。
1 つの代替方法は、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 ラムダ、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 のファンクターを使用したいという点を除いては似ています。、およびC++11 では、より柔軟で、余分な引数を処理します。この場合は次のようにしますが、一般に 2 引数のメンバー関数をバインドするには機能しません。bind1st
boost::bind
std::bind
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 では、ラムダを使用できます。
int compute_(int a, int b, int (test::*f)(int,int))
{
return compute_(a, b, [=](int c, int d){ return (this->*f)(c,d) });
}