C++ “编译时间图”;搜索“;在C++;

C++ “编译时间图”;搜索“;在C++;,c++,c++11,C++,C++11,我有下一个简化的回调映射。请原谅,如果代码包含一些错误,但它是一个非常简化的实际代码版本,可以在这里复制它 struct CallbacksMap { template<typename T, typename U> void Add(T* obj, void (T::*objCallback)(const U&)) { CallbackBaseType* c = new CallbackType<T, U>(obj, ob

我有下一个简化的回调映射。请原谅,如果代码包含一些错误,但它是一个非常简化的实际代码版本,可以在这里复制它

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;
};
struct CallbacksMap
{
模板
void Add(T*obj,void(T::*objCallback)(常量U&)
{
CallbackBaseType*c=新的回调类型(obj,objCallback);
_回调[std::type_index(typeid(U))]。回推(std::unique_ptr(c));
}
模板
无效删除(T*obj){…}
模板
无效调用(常量T和参数)
{
std::vector&callbacks=_callbacks[std::type_index(typeid(T))];
对于(自动回调=回调。开始();回调!=回调。结束();++回调)
{
(*回调)->调用(¶m);
}
}
std::map\u回调;
};
在这个示例中,我可以通过调用
call(param)
member函数来调用具有相同参数类型的所有函数。我的问题是,
\u callbacks
中的搜索是在运行时完成的,即使在编译时知道密钥也是如此

我不能基于类型的type_索引将回调列表静态地设置为模板函数的本地,因为我需要跟踪
Remove(t*obj)
函数的所有对象


您知道如何使内部结构能够避免这种运行时开销吗?

您可以将
callbackmap
作为模板:

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;
    }
};
模板
结构回调映射
{
模板
静态void Add(T*obj,void(T::*objCallback)(const U&)
{
CallbackBaseType*c=新的回调类型(obj,objCallback);
自动&callbacks=callbacks();
回调。push_back(std::unique_ptr(c));
}
静态无效删除(T*obj){…}
静态无效调用(常量T和参数)
{
自动&callbacks=callbacks();
对于(自动回调=回调。开始();回调!=回调。结束();++回调)
{
(*回调)->调用(¶m);
}
}
私人:

如果地图在编译时不知道,那么搜索怎么可能?这就是为什么我在标题中加入“搜索”,因为它不是真正的搜索…我认为这是缺乏灵感(标题真的很糟糕)我只需要一种方法来获取一个类型的回调列表,还需要获取一个所有已注册回调的列表,以便能够删除死掉的回调。您可以使用MPL来实现这一点,但您的回调不应该是T的成员函数。它们应该是一些类型。代码中还有一件奇怪的事情,回调是T的成员函数,接收U,但当调用时,只传递一个实例来调用…@kassak,我想调用所有具有U类型作为参数的成员函数的Ts
template <typename T>
void CallCallbacks(const T& param)
{
    CallbacksMap<T>(param);
}

CallCallbacks(param);