3

In this shortened example (not real world code), I'm attempting to call Callback with an int &, however, when going via the CallMethod method, the template parameter is interpreted as an int, meaning it can't convert it to the target parameter type.

Is this possible? I know I can cast the parameter to the correct type when calling CallMethod, however I'd like the solution to be implicit if possible.

#include <functional>
#include <iostream>

using namespace std;

void Callback(int &value)
{
    value = 42;
}

template <typename Method, typename ...Params>
void CallMethod(Method method, Params ...params)
{
    method(std::forward<Params>(params)...);
}

int main()
{
    int value = 0;
    CallMethod(&Callback, value);

    cout << "Value: " << value << endl;

    return 0;
}
Mark Ingram
  • 71,849
  • 51
  • 176
  • 230

1 Answers1

6

You aren't correctly forwarding your arguments. In order to make use of perfect-forwarding std::forward should operate on forwarding references, which are when you have an rvalue reference in a deduced context. Your CallMethod function should look like this:

template <typename Method, typename ...Params>
void CallMethod(Method method, Params&& ...params)
{
    method(std::forward<Params>(params)...);
}

Demo

TartanLlama
  • 63,752
  • 13
  • 157
  • 193
  • *"std::forward should operate on forwarding references"*, it's not true in general, for non-forwarding-reference types it just turns arguments taken by value into rvalues, which can then let you take advantage of move-constructing parameters taken by value in a function the argumnts are *forwarded* into – Piotr Skotnicki Jul 14 '15 at 10:16
  • @PiotrS. I don't completely understand what the use-case is, do you have a link or code sample I could look at? – TartanLlama Jul 14 '15 at 10:19
  • A classic example is [How std::function works](http://stackoverflow.com/q/14936539/3953764) – Piotr Skotnicki Jul 14 '15 at 10:21