我试图将函数参数中的数据存储到unordered_map中,其中unordered_map存储在另一个unordered_map中。在第二个unordered_map中,元素是一个结构。这是它的样子的简化版本:
//Callback.h
//Callback struct containing Object and Object function
struct CallbackStruct {
EXClass* object;
std::function<void()> function;
}
//Map with Keyboard keys as the key and CallbackStruct as the element
typedef std::unordered_map<Key, Callback> KeyCode;
//Map with an int as the key and KeyCode as the element
typedef std::unordered_map<int, KeyCode> BindingEvent;
class Callback {
public:
//This function takes the data and stores it
void bindKey(int Event, Key iKey, EXClass* classObj, std::function<void()> classFunction);
private:
//This is where the data is stored
BindingEvent handler;
}
//Callback.cpp
void Callback::bindKey(int Event, Key iKey, EXClass* classObj, std::function<void()> classFunction)
{
//This is where the function data is stored
CallbackStruct newCallback = { classObj, classFunction };
handler[Event][iKey] = newCallback;
}
现在效果非常好,但问题是
这仅适用于EXClass类。我需要这个适用于任何有权访问Callback.h的类
首先,我将CallbackStruct放在模板中。之后我必须将所有unordered_maps设置为模板。这意味着当我定义BindingEvent handler
时,它需要一个模板,这意味着你无法在类中定义它(可能?)。
我已经尝试将Callback类设置为模板,但是它不起作用,因为它只有初始化它的类的类。将在多个类之间共享单个Callback实例,并且模板需要与每个类一起使用。
这是我尝试过的源代码:
//InputManager.h
template <class T>
struct Callback {
T* Object;
std::function<void()> Function;
};
template <class T>
struct KeyCodeStruct { //I have to place these in structs because templates are not allowed in typedefs
typedef std::unordered_map<SDL_Keycode, Callback<T>> KeyCode;
};
template <class T>
struct BindingStruct{
typedef std::unordered_map<int, KeyCodeStruct<T>> Binding;
};
class InputManager {
public:
template <class T>
void bindInput(SDL_EventType eventType, SDL_Keycode key, Callback<T> f);
void updateInput(SDL_Event event);
private:
template <class T>
BindingStruct<T> bindingInput; //This is where the main issue is; Can't do this
};
答案 0 :(得分:1)
终于搞定了!虽然我仍然不确定是否可以在模板中使用数据结构,但我设法使我的Callback系统工作。我只需要使用std :: function和std :: bind。对于那些对最终结果感兴趣的人来说:
//InputManager.h
typedef std::function <void()> Callback;
typedef std::unordered_map<SDL_Keycode, Callback> KeyCode;
typedef std::unordered_map<int, KeyCode> Binding;
class InputManager {
public:
template <class T>
void bindInput(SDL_EventType eventType, SDL_Keycode key, T* newObj, void (T::*mf)())
{
inputBindings[eventType][key] = std::bind(mf, newObj);
};
void updateInput(SDL_Event event);
private:
Binding inputBindings;
};
...
//InputManager.cpp
void InputManager::updateInput(SDL_Event event)
{
while(SDL_PollEvent(&event)) {
if (inputBindings[event.type][event.key.keysym.sym])
inputBindings[event.type][event.key.keysym.sym]();
}
}