Sign in to follow this  
quant

functor

Recommended Posts

quant    100
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]

Share this post


Link to post
Share on other sites
snk_kid    1312
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.

Share this post


Link to post
Share on other sites
snk_kid    1312
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this