Re: Variadic templates and passing by reference
Am 11.03.2012 08:01, schrieb Thomas Richter:
how would you realize a variadic template function where you want to
pass in both scalar types and references you want to modify in the
callee. To be specific, consider declarations as follows:
class A;
template<class ...U>
void Launch(A &t,U&... other);
template<class ...U>
void Launch(int x,U&... other);
Now I get a problem because, when I want to call "Launch" with int
arguments as in
class A a,b;
Launch(a,5,b);
it clearly doesn't work. This would require the compiler to create a
reference to a temporary, which is of course not possible. Replacing the
arguments by const references would solve the problem as it would allow
the compiler to pass in references to temporaries. However, this
prohibits of course modification of the classes passed in, which I would
like to do. Replacing the reference by a copy would of course also solve
the problem of argument passing, but then I only modify the copy, so
this doesn't help either.
The problem you are describing is the so-called perfect-forwarding
problem, see e.g.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm
It was fixed by the introduction of rvalue-references plus a special
template argument rule in C++11. Just use
template<class ...U>
void Launch(A &t, U&&... other);
template<class ...U>
void Launch(int x, U&&... other);
and you are done. To understand why this works, it is important to
recognize that a function parameter of the form
T&&
of a function template with template parameter T will be deduced to
*either* an lvalue-reference type (if the argument is an lvalue) or the
non-reference type T (if the argument is an rvalue).
In your example the value '5' is an rvalue, so your first variadic
parameter will be deduced to int, and the effective parameter type int&&
accepts an int rvalue. The value 'b' is an lvalue, so your second
variadic parameter will be deduced to A&, which collapses in the
effective form "A& &&" to "A&".
Note that this rule only applies to *exact* this form. E.g. when declaring
template<class ...U>
void Launch(A &t, const U&&... other);
this value-dependent deduction does not happen. This function will only
accept rvalues for any U parameter.
HTH & Greetings from Bremen,
Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]