// (C) Porkolab 2003 // // A.6.20. // Member function adapter // This is syntax error! void draw_all(list<Shape*>& c) { for_each(c.begin(),c.end(),&Shape::draw); // oops! error } /* * In the STL: * */ template<class R, class T> class mem_fun_t : public unary_function<T*,R> { R (T::*pmf)(); public: explicit mem_fun_t(R (T::*p)()) :pmf(p) {} R operator()(T* p) const { return (p->*pmf)(); } // call through pointer }; template<class R, class T> mem_fun_t<R,T> mem_fun(R (T::*f)()) { return mem_fun_t<R,T>(f); } /* * Usage of a member function adapter * */ void draw_all(list<Shape*>& lsp) // call 0-argument member through pointer to object { for_each(lsp.begin(),lsp.end(),mem_fun(&Shape::draw)); // draw all shapes } /* * And the same with arguments * */ template<class R, class T> mem_fun_t<R,T> mem_fun(R (T::*f)()); // and versions for unary member, for const member, and const unary member (see table in _algo.adapter_) template<class R, class T> mem_fun_ref_t<R,T> mem_fun_ref(R (T::*f)()); // and versions for unary member, for const member, and const unary member (see table in _algo.adapter_) /* * Usage * */ void f(list<string>& ls) // use member function that takes no argument for object { typedef list<string>::iterator LSI; LSI p = find_if(ls.begin(),ls.end(),mem_fun_ref(&string::empty)); // find "" } void rotate_all(list<Shape*>& ls, int angle) // use member function that takes one argument through pointer to object { for_each(ls.begin(),ls.end(),bind2nd(mem_fun(&Shape::rotate),angle)); }