Re: variadic templates/unpacking pattern/perfect forwarding problem
Am 09.09.2013 22:50, schrieb hansewetz@hotmail.com:
Using an unpacking pattern in a variadic template together with
perfect forwarding does not seem to work (gcc 4.8). My understanding
is that the code below should compile (based on the reference
collapsing rules):
template<typename...Args>
void apply1(tuple<Args...>&&t){}
template<typename...Args>
void apply2(Args&&...t){}
...
tuple<int,string>t;
apply1(t); // compilation ERROR
apply2(t); // compiles OK
Any comments?
The line marked with "ERROR" is indeed ill-formed according to the
language. It has nothing to do with unpacking of variadic templates, but
instead with the fact that the first overload is not ruled by the
special "perfect forwarding"wording in [temp.deduct.call] p3,
"If P is an rvalue reference to a cv-unqualified template parameter and
the argument is an lvalue, the type ?lvalue reference to A? is used in
place of A for type deduction"
This is not the case in apply1 (but in apply2), because "tuple<Args...>"
does not correspond to "a cv-unqualified template parameter". To make
above call valid, you would need an rvalue as argument for apply1, e.g.
apply1(static_cast<tuple<int,string>&&>(t));
would make that happen.
If you want to use a single function template that allows both rvalues
and lvalues similar to apply2, you could use a constrained version of
apply2, e.g. something like:
template<class>
struct is_tuple : std::false_type {};
template<class... T>
struct is_tuple<tuple<T...>> : std::true_type {};
template<typename Arg>
typename std::enable_if<
is_tuple<
typename std::remove_cv<typename
std::remove_reference<Arg>::type>::type
>::value
>::type
apply1(Arg&&){}
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! ]