3

为什么 auto&& 不是右值引用?

Widget&& var1 = Widget(); // rvalue reference
auto&& var2 = var1; //var2 not rvalue reference

以下是右值参考示例

void f(Widget&& param); // rvalue reference
Widget&& var1 = Widget(); // rvalue reference

为什么 var2 不是右值引用,但 f 和 var2 是右值引用?

4

2 回答 2

5

auto&&是声明等价于转发引用(具有相同的扣除规则)。因此,当初始值设定项是左值时,它将被推导出为左值引用。但是,var是一个左值(因为它是一个变量的名称),因此var2是一个左值引用。

于 2016-01-20T12:17:09.703 回答
2

一旦确定了初始值设定项的类型,编译器就会auto使用函数调用的模板参数推导规则确定将替换关键字的类型(有关详细信息,请参阅模板参数推导#Other contexts)。关键字auto可以带有修饰符,例如constor &,这些修饰符将参与类型推导。

例如,给定

const auto& i = expr;

的类型i正是u虚数中参数的类型

template template<class U> 
void f(const U& u)

如果函数调用f(expr)已编译。

一般来说,可以这样想。

 template template<class U> 
    void f(paramtype u)

因此,auto&&根据初始值设定项,可以推断为左值引用或右值引用。

在你的情况下,想象的模板看起来像

 template template<class U> 
        void f(U&& var2){}
f(var1) 

在这里,var1被命名为右值,它被视为左值,因此var2将被推导出为左值。

考虑以下示例:

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&&
于 2016-01-20T12:29:47.867 回答