4

次に単純化されたコールバック マップがあります。コードにエラーが含まれている場合は申し訳ありませんが、ここで再現できるように実際のコードを非常に単純化したバージョンです。

struct CallbacksMap
{
    template<typename T, typename U>
    void Add(T* obj, void (T::*objCallback)(const U&))
    {
        CallbackBaseType* c = new CallbackType<T, U>(obj, objCallback);
        _callbacks[std::type_index(typeid(U))].push_back(std::unique_ptr<CallbackBaseType>(c));
    }

    template<typename T>
    void Remove(T* obj){...}

    template<typename T>
    void Call(const T& param)
    {
        std::vector<std::unique_ptr<T>>& callbacks = _callbacks[std::type_index(typeid(T))];
        for(auto callback = callbacks.begin(); callback != callbacks.end(); ++callback)
        {
            (*callback)->Call(&param);
        }
    }

    std::map<std::type_index, std::vector<std::unique_ptr<CallbackBaseType>>> _callbacks;
};

Call(param)このサンプルでは、​​メンバー関数を呼び出すことで、同じパラメーター型ですべての関数を呼び出すことができます。_callbacks私の問題は、コンパイル時にキーがわかっている場合でも、実行時に検索が行われることです。

関数のすべてのオブジェクトを追跡する必要があるため、型の type_index に基づいてテンプレート関数に対してコールバック リストを static ローカルにすることはできませんRemove(T* obj)

この実行時のオーバーヘッドを回避できるように内部構造を作成する方法を知っていますか?

4

1 に答える 1

2

CallbacksMapテンプレートを作成できます:

template<typename T>
struct CallbacksMap
{
    template<typename U>
    static void Add(T* obj, void (T::*objCallback)(const U&))
    {
        CallbackBaseType* c = new CallbackType<T, U>(obj, objCallback);
        auto& callbacks = callbacks();
        callbacks.push_back(std::unique_ptr<CallbackBaseType>(c));
    }

    static void Remove(T* obj){...}

    static void Call(const T& param)
    {
        auto& callbacks = callbacks();
        for(auto callback = callbacks.begin(); callback != callbacks.end(); ++callback)
        {
            (*callback)->Call(&param);
        }
    }

private:
    std::vector<std::unique_ptr<CallbackBaseType>& callbacks()
    {
        static std::vector<std::unique_ptr<CallbackBaseType> _callbacks;
        return _callbacks;
    }
};

このようにして、型の検索はコンパイラによって行われます。もちろん、これは、次のようなものを使用してコールバックを別の方法で呼び出す必要があることを意味します。

template <typename T>
void CallCallbacks(const T& param)
{
    CallbacksMap<T>(param);
}

CallCallbacks(param);
于 2013-03-22T15:14:10.737 に答える