#include <list>
#include <utility>
#include <iostream>
#define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))
class Base
{
public:
void doForAllDerived()
{
for (handlerList_t::const_iterator it = _registeredHandlers.begin(); it != _registeredHandlers.end(); ++it )
{
PrepFn pFn = (*it);
CALL_MEMBER_FN(*this, pFn )( 5 );
}
}
protected:
typedef void (Base::*PrepFn)( int n );
void registerPrepFn( PrepFn fn )
{
_registeredHandlers.push_back( fn );
};
private:
typedef std::list< PrepFn > handlerList_t;
handlerList_t _registeredHandlers;
};
class Derived : public Base
{
public:
Derived(int m) : _m(m) {
registerPrepFn( static_cast<PrepFn>(&Derived::derivedPrepFn) );
};
protected:
void derivedPrepFn( int n )
{
std::cout << _m << ", " << n << std::endl;
};
int _m;
};
int main() {
Derived anInstance(20);
anInstance.doForAllDerived();
}
I2luY2x1ZGUgPGxpc3Q+CiNpbmNsdWRlIDx1dGlsaXR5PgojaW5jbHVkZSA8aW9zdHJlYW0+CgojZGVmaW5lIENBTExfTUVNQkVSX0ZOKG9iamVjdCxwdHJUb01lbWJlcikgICgob2JqZWN0KS4qKHB0clRvTWVtYmVyKSkKCmNsYXNzIEJhc2UKewpwdWJsaWM6Cgl2b2lkIGRvRm9yQWxsRGVyaXZlZCgpCgl7CgkJZm9yIChoYW5kbGVyTGlzdF90Ojpjb25zdF9pdGVyYXRvciBpdCA9IF9yZWdpc3RlcmVkSGFuZGxlcnMuYmVnaW4oKTsgaXQgIT0gX3JlZ2lzdGVyZWRIYW5kbGVycy5lbmQoKTsgKytpdCApCgkJewkKCQkJUHJlcEZuIHBGbiA9ICgqaXQpOwoJCQlDQUxMX01FTUJFUl9GTigqdGhpcywgcEZuICkoIDUgKTsJCQoJCX0KCX0KCnByb3RlY3RlZDoKICAgIHR5cGVkZWYgdm9pZCAoQmFzZTo6KlByZXBGbikoIGludCBuICk7CgogICAgdm9pZCByZWdpc3RlclByZXBGbiggUHJlcEZuIGZuICkKICAgIHsKICAgICAgICBfcmVnaXN0ZXJlZEhhbmRsZXJzLnB1c2hfYmFjayggZm4gKTsKICAgIH07CiAgICAKcHJpdmF0ZToKICAgIHR5cGVkZWYgc3RkOjpsaXN0PCBQcmVwRm4gPiBoYW5kbGVyTGlzdF90OwogICAgaGFuZGxlckxpc3RfdCBfcmVnaXN0ZXJlZEhhbmRsZXJzOwp9OwogCmNsYXNzIERlcml2ZWQgOiBwdWJsaWMgQmFzZQp7CnB1YmxpYzoKICAgIERlcml2ZWQoaW50IG0pIDogX20obSkgewogICAgICAgIHJlZ2lzdGVyUHJlcEZuKCBzdGF0aWNfY2FzdDxQcmVwRm4+KCZEZXJpdmVkOjpkZXJpdmVkUHJlcEZuKSApOwogICAgfTsKCnByb3RlY3RlZDoKICAgIHZvaWQgZGVyaXZlZFByZXBGbiggaW50IG4gKQogICAgewoJCXN0ZDo6Y291dCA8PCBfbSA8PCAiLCAiIDw8IG4gPDwgc3RkOjplbmRsOwoJfTsKIAoJaW50IF9tOwp9OwogCmludCBtYWluKCkgewogICAgRGVyaXZlZCBhbkluc3RhbmNlKDIwKTsKICAgIGFuSW5zdGFuY2UuZG9Gb3JBbGxEZXJpdmVkKCk7Cn0K