2011-01-10 7 views
3

私は、コールバック関数とコールバック関数の引数の2つの引数を取るfunctionAを持っています。コールバックの引数は、intやユーザー定義の型のような型で構築できます。 functionAをどのように宣言できますか?コールバック関数のパラメータを渡す

eg: 
void functionA(void (*handler)(TYPEA), TYPEA variableA) 
{ 
    *handler(variableA); 
} 

TYPEAは組み込み型またはユーザー定義型です。ハンドラでdynamic_castingを使用して、typeAをコールバック関数に基づいて適切な型にキャストする必要がありますか(その場合、型Aはどうすればよいでしょうか?)、この場合はテンプレートを使用する必要がありますか?

+0

'functionA'は、' handler'を呼び出す以外に2番目の引数を使用しますか? –

答えて

1

TYPEAは、組み込みタイプ またはユーザー定義タイプです。

コールバック関数の引数の型が何かになる場合は、関数テンプレートが必要です。

template<class T> 
void function(void (*handler)(T), T variable) 
{ 
    handler(variable); 
} 
3

あなたはこのように渡すことができます:関数は、コールバック用以外の引数を使用しません

#include <iostream> 

template< typename A, typename B > 
void foo(A a, B b) 
{ 
    a(b); 
} 

void boo1(const int p) 
{ 
    std::cout<<"boo(" << p << ")" << std::endl; 
} 

void boo2(const std::string p) 
{ 
    std::cout<<"boo(" << p << ")" << std::endl; 
} 


int main() 
{ 
    foo(boo1, 3); 
    foo(boo2, "abc"); 
} 
+0

関数呼び出しの前に逆参照は不要であり、 'operator()'を多重定義するクラスの使用を禁止することができます。 –

+0

なぜですか?ファンクタそのものか、ファンクタへのポインタかを選択するのは単なる選択ではありませんか? – user168715

+1

私は@Chris Lutzに同意します。 @ user168715:そこに '*'を追加し、(関数ポインタの代わりに)ファンクタを使いたい場合は、あらかじめファンクタを作成して呼び出しのアドレスを抽出する必要があります。 '*'がなければ、その場でファンクタを作ることができます。つまり、特別な理由なしにファンクタの場合にユーザコードを書くのを難しくしています。 –

2

場合、私は完全にコールバックを削除します:

// c++0x, same can be achieved with boost::function/boost::bind in c++03 
void function(std::function< void (void) > f) 
{ 
    f(); 
} 
void callback1(int); 
void callback2(Type); 
//void callback3(double); 
void user_code() { 
    function(std::bind(callback1, 5)); 
    function(std::bind(callback2, Type(1, 2, 3, 4)); 
    // function(std::bind(callback3, 5.0); 
} 

functionの内部から渡された引数(none)のみを持つ汎用ファンクタ(std::function)を使用すると、関数をコールバックから分離します。コールバックの値はbindになります(コールバックの引数はfunctionの責任ではなく、functionは型や値について知る必要がありません)。

関連する問題