如何从函数指针调用非静态方法



我有一个类"人";像这样:

typedef void (*action)();
typedef std::unordered_map<int, action> keybindMap; // maps keycodes to functions
class Person {
keybindMap keybinds;
void doSomething();
}

我用它在正确的时间调用函数:

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.
}

为了绑定密钥,我使用了keybinds.insert_or_assign(SDLK_a, doSomething)。但是,这不起作用(因为doSomething是非静态的(。如何更改绑定代码和/或(*iter->second)()部分,以便可以调用等效于person.doSomething的内容?

非静态方法需要一个对象来调用它。普通函数指针没有空间容纳对对象的引用。

如果您将映射更改为包含std::function,则可以使用std::bind()或lambda将对象与方法指针相关联,例如:

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

另一方面,如果所有的目标方法都在同一个类/对象中,则可以使用普通方法指针而不是std::function,这将减少一些开销,例如:

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

最新更新