functor

Started by
2 comments, last by snk_kid 19 years, 6 months ago
Is there an stl equivalent of this functor?

template<typename T, typename R, typename U>
struct mem_func_param_imp{

	R operator()(U param) const{
		return (instance.*func)(param);
	}

	R (T::*func)(U);
	T& instance_;
};


I basically just want a functor which calls a member function of an object with the param as the argument. [Edited by - quant on October 1, 2004 5:23:41 AM]
-keyboard
Advertisement
One which is similar to that is std::mem_fun1_ref_t in the header functional there are varations on of these functors so there are 2 utility functions that will "deduce" the wright one for you the one that you'll need in this context is std::mem_fun_ref.

How-ever there is one problem thou the overloaded function call operator takes not just a templated arguement it also takes reference to an object to callback the member function, the reason is these where designed to be used with STL algorithms & containers.

Still there is away to achieve your goal using std::bind1st in conjunction with std::mem_fun_ref e.g.:

#include <functional>#include <iostream>struct foo {  void foobar(int i) const {     std::cout << "foo: " << i << '\n';  }};template < typename FooFighter >inline void callback(FooFighter f, int value) {   f(value);}int main() {   foo f;   callback(std::bind1st(std::mem_fun_ref(&foo::foobar), f), 40);    return 0;}


note bind1st & mem_fun_ref are just utility functions that will deduce and return an instance of the correct functor for you.

Granted it's not the nicest way you may wont to look at boost's function library or loki's functors.
thanks, thats great.
-keyboard
There is another way to create new functor type out of standard library type's std::mem_fun1_ref_t & std::binder1st you can resuse instead of doing the other above method.

While i was doing this i noticed a subtle problem with binder1st & binder2nd they don't overload the function call operators for non-const elements so the first solution i gave only works for member functions that are constant, but i got round that limitation with this:

#include <functional>#include <iostream>template < typename Op >class cbinder : public std::binder1st<Op> {   using std::binder1st<Op>::value;public:   explicit cbinder(const Op& x,                    const typename Opfirst_argument_type& y)   : std::binder1st<Op>(x, y) {}   typename Op::result_type operator()(const typename Op::second_argument_type& x) {      return op(value, x);   }};template < typename Type, typename Arg = void, typename Ret = void >struct Functor : public cbinder< std::mem_fun1_ref_t< Ret, Type, Arg > > {      typedef std::mem_fun1_ref_t< Ret, Type, Arg > mem_func;      typedef cbinder< mem_func > binder_type;   typedef Ret (Type::*func)(Arg);      explicit Functor(func f, const Type& t = Type())    : binder_type(mem_func(f), t) {}};struct foo {  void foobar(int i) {     std::cout << "foo: " << i << '\n';  }};int main() {   Functor< foo, int > func(&foo::foobar);   func(20);   return 0;}


Notice how you don't even need an instance of foo, still even that is quite limiting compared to what boost & loki have to offer.

This topic is closed to new replies.

Advertisement