I'm trying to implement an observer pattern (of sorts) with C++ and I want to use function pointer to do so, but I keep getting an error when trying to cast a function pointer from class B to a typedef function pointer:
#include <map>
typedef int (*OutputEvent)(const char*, const char*, int);
class A
{
private:
int nextListenerId;
std::map<int, OutputEvent> listenerMap;
public:
A(){ nextListenerId = 0;}
~A(){}
inline int RegisterListener(OutputEvent callback)
{
nextListenerId++;
listenerMap[nextListenerId] = callback;
return nextListenerId;
}
};
class B
{
private:
int listenerId;
public:
B(const A& a)
{
OutputEvent e = &B::CallMeBack;
listenerId = a.RegisterListener(e);
}
~B(){}
int CallMeBack(const char* x, const char* y, int z)
{
return 0;
}
};
I created this example and I've pasted it into codepad.org, but when I it fails to compile (it doesn't compile in codepad.org nor in Visual Studio 2010):
Output:
t.cpp: In constructor 'B::B(const A&)':
Line 28: error: cannot convert 'int (B::*)(const char*, const char*, int)' to 'int (*)(const char*, const char*, int)' in initialization
compilation terminated due to -Wfatal-errors.
I don't understand why it can't convert the function pointers. Could anybody help me please?
The function you are trying to cast to
OutputEvent
is a member function. This is represented clearly in the error message by this:which is a different type than
because of the
B::
part (that means that the function has an invisiblethis
parameter).If you define your member function as static, then you will be able to cast it to
OutputEvent
:The member function doesn't match the typedef'd prototype because member functions have an invisible 'this' parameter. Make it a static function and it should work.
The class member function has got a hidden parameter, the object, which the global function does not have.
Do something like this:-
More difficult if you have several callbacks on the go at the same time. But if there is only one you can have a pointer to the object and call via this.