C++存储来自模板函数的数据

C++ storing data from template function?

本文关键字:函数 数据 存储 C++      更新时间:2023-10-16

我正试图将函数参数中的数据存储到一个无序映射中,该无序映射存储在另一个无序贴图中。在第二个无序映射中,元素是一个结构。这是它的简化版本:

//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放置在一个模板中。在那之后,我不得不将所有的无序映射设置为模板。这意味着当我定义BindingEvent handler时,它需要一个模板,这意味着你不能在类中定义它(也许?)。

我曾尝试将回调类设置为模板,但这不起作用,因为它只有初始化它的类的类。回调的单个实例将在多个类之间共享,模板需要与每个类一起使用。

这是我尝试过的源代码:

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

终于拿到了!虽然我仍然不确定是否可以在模板中使用数据结构,但我还是设法让我的回调系统正常工作。我只需要使用std::函数和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]();
    }
}