Compile a temporary search map in C ++

I have the following simplified callback map. Please excuse me if the code contains some erros, but this is a very simplified version of the real code to reproduce it here.

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; }; 

In this example, I can call all functions with the same parameter type by calling the Call(param) member function. My problem is that _callbacks performed at runtime, even if the key is known at compile time.

I cannot make the callback list static local for the template function based on the type_index of this type, because I need to track all the objects for the Remove(T* obj) function Remove(T* obj) .

Do you know how I can get the internal structure to avoid this overhead at runtime?

+4
source share
1 answer

You can create a CallbacksMap template:

 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; } }; 

Thus, the type search is performed by the compiler. Of course, this means that you have to call the callback differently using something like:

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

All Articles