How to register a derived class member function pointer with a base class
c++, pointer-to-member
Solution
This pattern can be handled with the Curiously Recurring Template Pattern, that is, compile-time polymorphism.
The code below compiles without a cast.
template <class D>
class Base {
protected:
typedef void (D::*PrepFn) (int n);
void registerPrepFn(PrepFn fn) {}
Base() {};
Base(PrepFn fn) {
registerPrepFn(fn);
}
};
class Derived : public Base<Derived>{
Derived() {
registerPrepFn( &Derived::derivedPrepFn);
}
void derivedPrepFn( int n) {};
};
class Derived2 : public Base<Derived2> {
Derived2() : Base(&Derived2::derived2PrepFn) {}
void derived2PrepFn(int n) {}
};
To my taste, the version with `Derived2` is even better, because you push registration up into the base class. By deleting the default `Base` constructor (can't do that here, would break `Derived`), you can force derived classes to supply a pointer-to-member function with the correct signature.
Problem
As opposed to virtual member functions, I need a solution where a function implemented at each level class derivation can be registered for later call by the base class. ( Not just the most derived implementation) To do this, I was thinking on providing a mechanism for derived classes to register their function with the base class such as during the derived class constructor. I'm having trouble with the member function pointer argument though. I was thinking that Derived is derived from Base, the `this` pointer should be automatically casted. Can this be done close to what I am trying or do I need to use static member functions, `void *`, and `static_cast`? ``` class Base { protected: typedef void (Base::*PrepFn)( int n ); void registerPrepFn( PrepFn fn ) {}; } class Derived : public Base { Derived() { registerPrepFn( &Derived::derivedPrepFn ); }; void derivedPrepFn( int n ) {}; } ``` Compiler error: ``` error: no matching function for call to 'Derived::registerPrepFn(void (Derived::*)(int))' note: candidates are: 'void Base::registerPrepFn(void (Base::*)(int))' ```