6 に答える
@ steveo225が指摘したようにf
、そのコンテキストでvoid (a::*)(int)
はvoid (*)(int)
. これを修正するには 2 つの方法があります。1 つ目は、b::foreach_x_do
任意の呼び出し可能な型を取るメンバー関数テンプレートを作成することです。
class b {
int* x;
public:
b() : x() { }
template<typename F>
void foreach_x_do(F f) {
while(*x++)
f(*x);
}
};
class a {
b b_inst;
public:
void f(int x) { }
a() : b_inst() {
b_inst.foreach_x_do(std::bind(&a::f, this, _1));
}
};
b::foreach_x_do
2 つ目は、非テンプレートを保持しstd::function<>
、関数ポインターの代わりに を取得することです。
class b {
int* x;
public:
b() : x() { }
void foreach_x_do(std::function<void(int)> const& f) {
while(*x++)
f(*x);
}
};
class a {
b b_inst;
public:
void f(int x) { }
a() : b_inst() {
b_inst.foreach_x_do(std::bind(&a::f, this, _1));
}
};
どちらの場合でも、コンパイラが古すぎてorの実装を同梱できない場合は、 std::bind
andstd::function
を対応するものに置き換えます。また、C++11 コンパイラを使用している場合は、の代わりにラムダを使用できることにも注意してください。boost::
std::
std::tr1::
bind
次のようにする必要があります。
b_inst.foreach_x_do(f);
関数の元のシグネチャは、メンバー関数へのポインターではなく、スタンドアロン関数ポインター用であるためf
、非静的メンバーメソッドではなく、静的にする必要もあります。foreach_x_do
つまり、
static void f(int x) { }
関数for_each_x_do
は関数ポインターを期待していますが、メンバー関数ポインターを (しようとして) 与えようとしています。2つは同じではありません。前者は直接呼び出すことができますが、後者はオブジェクト インスタンスを呼び出す必要があります。std::function
またはboost::function
代わりに使用することをお勧めします。何かのようなもの:
void for_each_x_do(function<void (int)> f) {
// your code here
}
次に、バインダーを使用して関数オブジェクトを作成します。
a(){
b_inst.foreach_x_do(bind(&a::f, this, _1));
}
この行で:
b_inst.foreach_x_do(f)();
2 番目の括弧のセットを削除します。それらは必要ありません。
b_inst.foreach_x_do(f);
正常に動作するはずです。
f()
メンバー関数なので、関連性は対応するオブジェクトに限定されます。これまでのところ、これらのソリューションの一部は機能しません。
2 つの選択肢があります。関数を静的にする (この場合、どのオブジェクトでも問題ありません) か、何らかの形でオブジェクトを渡すかです。
2 番目の方法は、メンバー関数の受け渡しに関するこの役立つ FAQで明確に説明されています。
試す:
class b{
int *x;
public:
void foreach_x_do(void (*f)(int)){
while(*x++) // or any kind of iteration through x
(*f)(*x);
}
};