I have a class "Person" like so:
typedef void (*action)();
typedef std::unordered_map<int, action> keybindMap; // maps keycodes to functions
class Person {
keybindMap keybinds;
void doSomething();
}
I use this to call the functions at the right times:
iter = keybinds.find(event.key.keysym.sym); // event.key.keysym.sym is the key code
if (iter != keybinds.end())
{
(*iter->second)(); // call whatever function that key is bound to.
}
To bind a key, I used keybinds.insert_or_assign(SDLK_a, doSomething). However, this doesn’t work (because doSomething is non-static). How do I change the binding code and/or the (*iter->second)() part so that I can call something equivalent to person.doSomething?
>Solution :
A non-static method requires an object to call it on. An ordinary function pointer doesn’t have room to hold a reference to an object.
If you change your map to hold std::function instead, you can then use std::bind() or a lambda to associate an object with a method pointer, eg:
using action = std::function<void()>;
using keybindMap = std::unordered_map<int, action>;
class Person {
keybindMap keybinds;
void doSomething();
};
...
Person p, otherP; //must outlive the map...
p.keybinds[...] = [&otherP](){ otherP.doSomething(); }
...
iter = keybinds.find(event.key.keysym.sym);
if (iter != keybinds.end()) {
iter->second();
}
On the other hand, if all of the target methods are in the same class/object, you can use a plain method pointer instead of std::function, which will reduce some overhead, eg:
class Person {
using action = void (Person::*)();
using keybindMap = std::unordered_map<int, action>;
keybindMap keybinds;
void doSomething();
};
...
keybinds[...] = &Person::doSomething;
...
iter = keybinds.find(event.key.keysym.sym);
if (iter != keybinds.end()) {
(this->*(iter->second))();
}