0
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"?

10
  • I don't have a full answer, but perhaps std::is_member_function_pointer might help a bit. Commented Mar 11, 2014 at 12:43
  • You can do (a.*func)(a) as well if you omit the first argument. Commented Mar 11, 2014 at 12:48
  • @RichardJ.RossIII: Thanks! but these are for C++11. Commented Mar 11, 2014 at 13:04
  • @0x499602D2 I did not get it. could you please elaborate? Commented Mar 11, 2014 at 13:04
  • 3
    You cannot call a member function without an object instance, are you aware of that? Commented Mar 11, 2014 at 13:13

2 Answers 2

5

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);
}
Sign up to request clarification or add additional context in comments.

1 Comment

This pretty much says it all I guess. You are right. It s impossible to do it like I wanted.
1

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.

9 Comments

You forgot the argument types (you specialize for data member pointer, currently). And what's the point? OP already has C in func's template parameter list.
@jrok the OP wasn't really clear, but I interpreted it as he wanted to induce (and remove) the type of the first parameter, which is either A* or C*.
+1 Wow I'm glad I remembered using this weird syntax to define a pointer to function myself; otherwise I'd also wondered why R C::* matches a pointer-to-member-function. You might want to add some explanation how it works.
I m a bit lost in your code. I thought it would be pretty much straightforward. but If I cannot find another answer I will mark it as an answer. Thanks @RichardJ.RossIII. Agree with dyp. Some explanation might help a lot
@dyp I'm stumped. Why does this match a pointer to member function?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.