Home > Blockchain >  How to call a non-static method from a function pointer?
How to call a non-static method from a function pointer?

Time:02-08

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?

CodePudding user response:

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))();
}
  •  Tags:  
  • Related