次に単純化されたコールバック マップがあります。コードにエラーが含まれている場合は申し訳ありませんが、ここで再現できるように実際のコードを非常に単純化したバージョンです。
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(¶m);
}
}
std::map<std::type_index, std::vector<std::unique_ptr<CallbackBaseType>>> _callbacks;
};
Call(param)
このサンプルでは、メンバー関数を呼び出すことで、同じパラメーター型ですべての関数を呼び出すことができます。_callbacks
私の問題は、コンパイル時にキーがわかっている場合でも、実行時に検索が行われることです。
関数のすべてのオブジェクトを追跡する必要があるため、型の type_index に基づいてテンプレート関数に対してコールバック リストを static ローカルにすることはできませんRemove(T* obj)
。
この実行時のオーバーヘッドを回避できるように内部構造を作成する方法を知っていますか?