I just created a pretty neat callback mechanism for C++:
template<typename T>
class callback {
public:
callback(T* obj, unsigned int (T::*func)(string, ostream&, header_container&, cgiparam_container& ))
: callee(obj), cb(func) { }
~callback();
unsigned int run(string actionstr, ostream& os, header_container& hdrs, cgiparam_container& params) {
return (callee->*cb)(actionstr,os,hdrs,params);
}
private:
T* callee;
unsigned int (T::*cb) (string,ostream&, header_container&, cgiparam_container& );
};
class context {
public:
context();
~context();
unsigned int dispatch_action(string actionstr, ostream& os, header_container& hdrs, cgiparam_container& cgiparams);
protected:
void register_action(string,callback<context>*);
private:
map<string,callback<context>*> actions;
};
The implementation of register_action() looks like this:
void context::register_action(string action, callback<context>* cb) {
actions[action] = cb;
}
And this is used in the following way (called from within the context class):
register_action("foobar",new callback<context>(this,&context::some_method));
Now, the problem that I have is that that adding callbacks that are not actually within the context class but within a derived class is only possible with lots of ugly casting (but it seems to work afterwards):
#define REGISTER_ACTION(name,action) do { register_action((name),new callback<context>((context*)this, (unsigned int (context::*)(std::string, std::ostream&, net::header_container&, net::cgiparam_container&))&action)); } while(0)
Do I see correctly that C++ seems to have certain problems with derived classes and templates, especially when it comes to using pointers to methods? Any input is welcome on how to remove this ugly casting while keeping the same functionality.