Question

template<typename C, typename Arg>
int foo(C* c, int (C::*func)(Arg), Arg a)
{
  c->*func(a);
}

to call the 'foo', we have to pas both A* and &A::bar,

foo(A*,&A::bar,var);

Is there a way to define the template (e.g as a struct) such that there is no need to pass "A*"? how can I define a template which gets A* from "&A::bar"?

Was it helpful?

Solution

You can't avoid passing the instance if you want to call a non-static method on that instance, unless you don't mind calling it on a temporary, default-constructed instance:

template<typename C, typename Arg>
int call_on_temp(int (C::*func)(Arg), Arg a)
{
    C temp;
    temp.*func(a);
}

or the caller explicitly binds the instance into a functor:

template<typename F, typename Arg>
int call_on_functor(F func, Arg a)
{
    func(a);
}

which makes the call site ugly:

call_on_functor(std::bind(std::mem_fn(&Class::method), instance), arg);

(and you still need the instance, you've just moved it from one place to another).

Note that you can infer the type of A from the function pointer, you just can't infer an instance to call your function on. If you want to call a static method, you don't need the class type at all:

template<typename Arg>
int call_on_static(int (*func)(Arg), Arg a)
{
    func(a);
}

OTHER TIPS

This should do what you need it to:

template<typename unused>
struct member_function_pointer_type_helper;

template<typename R, typename C>
struct member_function_pointer_type_helper<R C::*> {
    typedef C type;
};

template<typename F>
struct member_function_pointer_type : member_function_pointer_type_helper<typename std::remove_cv<F>::type> {
};

Example:

struct A { void foo() { ... } };


typedef member_function_pointer_type<decltype(&A::foo)>::type a_type; // 'A'

a_type my_a;
my_a.foo(); 

This works by having a specialized template for only member functions, and then simply exports the class part of that member function.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top