/*
* Member Funstion Adapter
*
*/
// That 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));
}