Let foo be the function:
template< typename T >
void foo( T&& a ){}
To what type will T be deduced for the following calls of foo:
foo( 0 ); // is T here int or int&& ?
int a = 0;
foo( a ); // is T here int or int& ?
The default rule for type deduction is that reference types can never be the result of deduction. Given this code,
template <class T>
void bar(T par);
bar(0);
int a;
bar(a);
int &b;
bar(b);
all 3 calls will call foo<int>. That is, T is deduced to int and par is of type int.
Forwarding references work by simple addition of one rule: when the argument used for type deduction of a forwarding reference (i.e. of a parameter T&& for a deduced T) is an lvalue of type X, the type X & is used instead of X for deduction.
Note that this means that given a type X, only X or X & can ever be the result of type deduction; X && never can.
Let's analyse your code (I will rename he function parameter, to make it clear what I'm referring to):
template <class T>
void foo(T &&par);
foo(0);
int a;
foo(a);
In the first case foo(0), the argument is an rvalue of type int The type int is therefore used for type deduction, meaning that T is deduced to int (the function called is foo<int>) and the type of par is int &&.
In the second case foo(a), the argument is an lvalue of type int. Forwarding reference rule kicks in and the type int & is used for deduction. T is therefore deduced to int & (the function called is foo<int&>), and the type of par is "int & &&", which collapses to int &.
The expression T&& in a deduced context like what you provided
template< typename T >
void foo( T&& a ){}
ie T is deduced based on the provided argument, is subject to reference collapsing rules.
In short;
if the provided argument is an lvalue of type type, T&&
will expand to type& && that collapses to type&
if the provided argument is an rvalue of type type, T&&
will expand to type && that collapses to type&&
Note that both are references, if you need to trigger the rvalue
overload of another function, you need to do std::forward<T>(a)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With