Answer the question
In order to leave comments, you need to log in
A pointer to a class member function. How to decide?
I have map <std::string, void (*)()> keyEvents
Here I need to set a new element to the map: a method of an object of type Script. But the compiler swears and says incorrect type conversion.
void KeyEvent::Subscribe(Script* script)
{
keyEvents["KeyPress"] = script->OnKeyPress;
}
Script::Script()
{
KeyEvent::Subscribe(this);
}
keyEvents["KeyPress"]();
virtual void OnKeyPress() = 0;
Answer the question
In order to leave comments, you need to log in
You need it std::bind
to curry your method. A non-static method must implicitly take as its first parameter a pointer to the object on which it is called. The same this. Those. a method with no parameters is actually a function with 1 parameter. It is this parameter that needs to be fixed, turning the method into a real function without parameters.
#include <functional>
#include <iostream>
#include <string>
#include <map>
class Foo {
public:
Foo(std::string msg): m_msg(msg) {}
void event() {
std::cout << m_msg << std::endl;
}
private:
std::string m_msg;
};
int main() {
auto foo = new Foo("Foo");
auto bar = new Foo("Bar");
std::map<std::string, std::function<void ()>> keyEvents = {
{"foo", std::bind(&Foo::event, foo)},
{"bar", std::bind(&Foo::event, bar)}
};
for(auto callback: keyEvents) {
std::cout << callback.first << ":";
callback.second();
}
keyEvents.clear();
delete foo;
delete bar;
return 0;
}
In C++, class methods differ from regular functions and static class methods in that they
have an additional hidden parameter per class instance.
For this reason, you cannot pass KeyEvent::Subscribe to void (*)() type.
To store a pointer to your class method, you must declare the type like this:
But in this case, you get a hard binding to this class.
If you need methods of different classes, then it is better to solve such a problem through interfaces.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question