"Jonathan Mcdougall" <> wrote...
> To make a long story short, I need to associate events with pointers
> to functions. The first idea which came to my mind was
>
> enum Event
> {
> clicked,
> moved
> };
>
> typedef void (*Handler)(int);
>
>
> void my_handler(int)
> {
> std::cout << "in my handler";
> }
>
>
> int main()
> {
> std::map<Event, Handler> handlers;
>
> handlers.insert(std::make_pair(clicked, &my_handler));
>
> if ( event_triggered(clicked) )
> (handlers[clicked])( /*whatever*/ );
> }
>
>
> I hope this makes sense.
>
> Now, the thing is, I need to include member functions too, so I came
> up with that :
>
> template<class Object, class Function> class Handler
> {
> private:
> Object obj_;
> Function fun_;
>
> public:
> template<class Object, class Function>
> Handler(Object obj, Function fun)
> : obj_(obj),
> fun_(fun)
> {
> }
>
> void operator()(int whatever)
> {
> ((*obj_).*fun_)(whatever);
> }
> };
>
> But now I am stuck with the std::map, since it cannot accept templates
> (as I understand).
>
> Could anybody show me a way of acheiving the equivalent results?
Nothing can accept templates. Everything has to eventually boil down
to become a concrete class or function. Since you cannot store different
instantiations of your template class 'Handler' in the same map, you need
to play the polymorphic card:
#include <map>
using std::map;
enum Event { Clicked, Moved };
class BaseHandler {
public:
~BaseHandler() {}
virtual void operator()(int whatever) = 0;
};
template<class Object> class Handler
: public BaseHandler {
public:
typedef void (Object::*Function)(int);
private:
Object* obj_;
Function fun_;
public:
Handler(Object* obj, Function fun)
: obj_(obj), fun_(fun)
{
}
void operator()(int whatever)
{
(obj_->*fun_)(whatever);
}
};
template<class Object> Handler<Object>*
makeHandler(Object* obj,
typename Handler<Object>::Function fun) {
return new Handler<Object>(obj, fun);
}
class ClickHandler {
public:
void doit(int);
};
int main() {
map<Event, BaseHandler*> myhandlers;
ClickHandler cH;
myhandlers[Clicked] = makeHandler(&cH, &ClickHandler::doit);
// use it and then _delete_ every entry in the map
}
I haven't got this to execute, besides, there is no code to use the
map, but you should get the idea...
Victor
|