![]() |
Re: std::map of pointers to member functions
"Jonathan Mcdougall" <DELjonathanmcdougall@yahoo.ca> 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 |
Re: std::map of pointers to member functions
>> 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. It makes sense, I still have some difficulties understanding, or visualizing, templates. >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 > } > Wow. It took me a while to integrate it (since I am not very good with templates), but it works like a charm, as your solutions always do. Thank you, Jonathan |
| All times are GMT. The time now is 03:42 PM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.