6

I want to create a wrapper class which is able to call member functions (of any type) of the wrapped class with help of templates. This is what I have so far:

template <typename T>
class wrapper {
  public:    
    template<typename R, R (T::*func)()>
    void call_func() {
      (wrapped.*func)();
    }

  private:
    T wrapped;  
};

class some_class {
  private:
    int i = 2;
  public:
    void some_func() {
      std::cout << i << std::endl;
    }
};

int main() {
    wrapper<some_class> wr;
    // How I need to call at the moment:
    wr.call_func<void, &some_class::some_func>();
    // How I want call:
    wr.call_func<&some_class::some_func>();
    return 0;
}

As you can see in the comments of the main function, I want to call the wrapper-function without explicitly specifying the return type of the wrapped member function. (How) Can this be done in C++11?

2 Answers 2

10
template<typename F>
void call_func(F func) {
  (wrapped.*func)();
}

then call like this:

wr.call_func(&some_class::some_func);

If you want to use the return value too, you'll need this:

template<typename F>
auto call_func(F func) -> decltype((std::declval<T>().*func)()) {
  return (wrapped.*func)();
}

If you have C++14, you can omit the -> decltype(...) part and use decltype(auto) as the return value.

If you also want to pass functions, you can use variadic templates and forwarding for that.

template<typename F, typename... Args>
decltype(auto) call_func(F func, Args&&... args) {
  return (wrapped.*func)(std::forward<Args>(args)...);
}
Sign up to request clarification or add additional context in comments.

5 Comments

Isn't it possible to pass the member function as template parameter instead of function parameter?
@MikevanDyke There is, as it is in the question. But why do you want it that way?
If you have C++14 and omit the decltype, you should substitute the return type for decltype(auto) to conserve the same semantics for the template.
@petersohn Because I want to pass some arguments too and that way, I could seperate the function from the arguments. It would just look kind of "cleaner" to me.
@MikevanDyke I added the usage of arguments to the answer.
0

You can directly use std::function

For more information on std::function see: http://en.cppreference.com/w/cpp/utility/functional/function

1 Comment

That one works, but not very efficient. std::function is useful if you want to save the call for later.

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.