14

私はコールバックメカニズムを持っています、関係するクラスは次のとおりです:

class App
{
    void onEvent(const MyEvent& event);
    void onEvent(const MyOtherEvent& event);

    Connector connect;
}

class Connector
{  
   template <class T> void Subscribe(boost::function <void (const T&)> callback);
}

App::App()
{
    connect.Subscribe<MyEvent>(&App::OnEvent<MyEvent>);
}

まず、このコードはコンパイルされません。これはイラストです。

テンプレートを使用すると例が複雑になりますが、問題に影響するため、テンプレートを残しました。Connectorクラスは、処理するイベントタイプの数を認識していないため、サブスクライブをテンプレート化する必要があることは確かです。私が作成しようとすると:

boost::function f = &App::OnEvent, 

OnEventを特殊化を使用してテンプレート関数として作成しようとしましたが、コンパイラがOnEvent関数をテンプレート特殊化ではなくオーバーロードとして処理しているようです。そうでない場合、明示的に宣言しようとすると、名前空間エラーではなくテンプレート特殊化が発生します。

template <> OnEvent(const MyEvent& e) ...

私はコンパイルするために以下を得ることができます:

boost::function <void (App*, const MyEvent&)> f = &App::OnEvent;
f(this, e); 

これは、コンパイル、実行、および動作します。

boost::function<void (const MyEvent&)> g = boost::bind(&App::OnEvent, this);

ではない。オーバーロードされた関数のアドレスを正しく指定していないためだと思います。

これをすべてテディベアに説明したので、私の質問は「オーバーロードまたはテンプレート化されたメンバー関数への関数ポインターを正しく作成し、このポインターをそれにバインドするにはどうすればよいですか?」だと思います。

4

2 に答える 2

33

オーバーロードされた関数のアドレスを明確にする必要があると思います。これを行うには、関数ポインターを正しいパラメーターを持つものに明示的にキャストします。

boost::bind( static_cast<void (App::*)( MyEvent& )>(&App::OnEvent) , this, _1);

gamedev.netの同様の問題と解決策

于 2009-12-16T19:41:55.407 に答える
4

あなたがしたい

boost::function<void (const MyEvent&)> g = boost::bind(&App::OnEvent, this, _1);

g(event);を実行できるはずです。それと

ここで何を達成しようとしているのかよくわかりませんが、今のところ問題の1つは解決するはずです。

于 2009-12-16T16:58:00.993 に答える