In many applications, you need a generic class that invokes callback functions regardless of their class type. For example, an even-driven system that needs to call a member function of a GUI component without knowing its actual type. You can create a generic callback class template to streamline this task. Such a template takes the class whose member function is to be called as its first parameter. The second template parameter is a pointer to that class’s member function. The trick is that you base the second parameter on the first one, as follows:
template < class T, void (T::*F)() > class callback {/**/};
The implementation of the template is relatively simple: it has a reference to T, which is the class whose member function is to be called, a constructor and a member function called execute(), which invokes the callback member function:
template < class T, void (T::*F)() >class callback{public: callback(T& t) : object(t) {} // assign actual object to T void execute() {(object.*F)();}// launch callback functionprivate: T& object;};
Remember that in order to call a member function through a pointer to member, you must have a reference or pointer to the actual object. This is why the template has a T& as a data member. Now suppose we want to use the callback template to execute a callback member function of class A:
class A{public: void f();};
Here’s how you instantiate the template: a template argument must be a constant expression. Therefore, you can’t use a variable as the address of the member function. Instead, use the & operator to take the function’s address. Finally, pass the object whose member function you want to be called as the argument for the template object:
int main(){ A a; // first, create an object callback < A, &A::f > c(a); // instantiate template c.execute(); // call callback member function}
You can use the callback class template with any class type, as long as the member function called has the same signature.