I'm trying to implement an event manager based on the linked code in the top answer here: Game Objects Talking To Each Other
However I'm getting an error when I try to register the callbacks. I'm sure it has to do with the typedef, and I admit I'm not sure how it works exactly, but it is in the exact same form in the linked code. The B class should be inherriting from the Interface, so why is the type different? I've condensed the code into the smallest example below.
#include <iostream>
class Interface;
typedef void (Interface::*Callback)(void *data);
class Interface
{
public:
void Register (Callback func);
};
void Interface::Register(Callback func)
{
std::cout << "Register" << std::endl;
}
class B : public Interface
{
public:
B();
void Echo(void *data);
};
B::B()
{
Register( (Callback)Echo );
}
void B::Echo(void *data)
{
std::cout << "Echo" << std::endl;
}
int main()
{
B b;
return 0;
}
Here's the error I get under g++ 4.6.1:
test.cpp: In constructor ‘B::B()’:
test.cpp:31:22: error: argument of type ‘void (B::)(void*)’ does not match ‘Callback {aka void (Interface::*)(void*)}’
Could anyone please explain what I'm doing wrong? Thanks
As @Kerrek correctly pointed out, Echo
is not a member of Interface
, therefore B::Echo
doesn't qualify as Interface::*Callback
. But you can use a template to accomplish that, e.g.:
template <class T> class Interface {
public:
typedef void (T::*Callback)(void *data);
void Register(Callback func) {
std::cout << "Register" << std::endl;
}
// ...
};
class B : public Interface<B> {
public:
B() {
Register(&B::Echo);
}
void Echo(void *data) {
// Do something
}
};