13

ライブラリ コード:

class Resource 
{
public:
    typedef void (*func_sig)(int, char, double, void*);
//Registration
    registerCallback(void* app_obj, func_sig func)
    {
        _app_obj = app_obj;
        _func = func;
    }

//Calling when the time comes
    void call_app_code()
    {
        _func(231,'a',432.4234,app_obj);
    }
//Other useful methods
private:
    void* app_obj;
    func_sig _func;
//Other members
};

アプリケーション コード:

class App
{
public:
    void callme(int, char, double);
//other functions, members;
};

void callHelper(int i, char c, double d, void* app_obj)
{
    static_cast<App*>(app_obj)->callme(i,c,d);
}

int main()
{
    App a;
    Resource r;
    r.registercallback(&a, callHelper);
//Do something
}

上記は、コールバック メカニズムの最小限の実装です。これはより冗長であり、std::function のようにバインディングやプレースホルダーなどをサポートしていません。std::function上記のユースケースにorを使用するboost::functionと、パフォーマンス上の欠点はありますか? このコールバックは、リアルタイム アプリケーションの非常に重要なパスになります。boost::function は仮想関数を使用して実際のディスパッチを行うと聞きました。バインディング/プレースホルダーが含まれていない場合、最適化されますか?

アップデート

最新のコンパイラでアセンブリを検査することに関心がある場合: https://gcc.godbolt.org/z/-6mQvt

4

3 に答える 3

9

std::function関数型で型消去を実行し、それを実装する方法は複数あるため、正確な答えを得るには、使用しているコンパイラのバージョンを追加する必要があります。

boost::functionstd::functionはとほぼ同じで、コール オーバーヘッドに関する FAQエントリとパフォーマンスに関する一般的なセクションが含まれています。これらは、関数オブジェクトがどのように機能するかについてのヒントを与えてくれます。これがあなたのケースに当てはまる場合は、実装によって異なりますが、数値に大きな違いはありません。

于 2013-01-13T18:12:14.233 に答える