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