C ++存储模板函数的数据?

时间:2014-09-22 19:43:41

标签: c++ templates callback unordered-map

我试图将函数参数中的数据存储到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
};

1 个答案:

答案 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]();
    }
}