问题
Why auto&& is not rvalue reference?
Widget&& var1 = Widget(); // rvalue reference
auto&& var2 = var1; //var2 not rvalue reference
below are rvalue reference example
void f(Widget&& param); // rvalue reference
Widget&& var1 = Widget(); // rvalue reference
Why var2 is not rvalue reference but f and var2 are rvalue references?
回答1:
Once the type of the initializer has been determined, the compiler determines the type that will replace the keyword auto
using the rules for template argument deduction from a function call (see template argument deduction#Other contexts for details). The keyword auto
may be accompanied by modifiers, such as const
or &
, which will participate in the type deduction.
For example, given
const auto& i = expr;
The type of i
is exactly the type of the argument u
in an imaginary
template template<class U>
void f(const U& u)
If the function call f(expr)
was compiled.
In general , it can be think as below .
template template<class U>
void f(paramtype u)
Therefore, auto&&
may be deduced either as an lvalue reference or rvalue reference according to the initializer.
In your case , imaginary template would look like
template template<class U>
void f(U&& var2){}
f(var1)
Here ,var1
is named rvalue which is being treated as lvalue, so var2
will be deduced as lvalue .
Consider the following examples:
auto&& var2 = widget() ; //var2 is rvalue reference here .
int x=10;
const int cx=10;
auto&& uref1 = x; // x is int and lvalue, so uref1's type is int&
auto&& uref2 = cx; // cx is const int and lvalue, so uref2's type is const int&
auto&& uref3 = 27; // 27 is int and rvalue, so uref3's type is int&&
回答2:
auto&&
is a declaration's equivalent of forwarding references (with identical deduction rules). As such, it will be deduced to an lvalue reference when the initializer is an lvalue. However, var
is an lvalue (as it is the name of a variable), hence var2
is an lvalue reference.
来源:https://stackoverflow.com/questions/34899538/auto-variables-are-not-rvalue-reference