为什么 auto&& var2 不暗示右值引用?

Why does auto&& var2 not imply rvalue reference?

为什么auto&& var2在下面的代码中不是指右值引用?

如果能对这个问题有所帮助,我将不胜感激。

Widget&& var1 = someWidget;      // here, “&&” means rvalue reference
auto&& var2 = var1;              // here, “&&” does not mean rvalue reference

鉴于 Widget&& var1 是一个 右值引用 ,为什么它不是 右值

为什么auto&& var2 = var1;不是右值引用?

Given that Widget&& var1 is an rvalue reference, why isn't it an rvalue?

someWidgetvar1var2 都有一个名称,因此,无论它们的声明类型如何,它们都是 左值 .

右值引用是关于类型的引用var1,而项rvalue 是关于表达式 var1:

值类别
  • var1 声明为 Widget&& var1reference to Widget,特别是 rvalue reference to Widget (i.e., Widget&&) – 这是 var1type,这是一个引用。引用类型告诉你如何初始化引用:右值引用只能用右值初始化,而非[=29] =] 左值引用只能用左值初始化。

  • 当在表达式中使用 var1(没有用 std::move 标记)时,var1 是一个 lvalue 因为它有一个名称 – 这是 var1 值类别 ,它是正交于其类型的表达式 var1 的 属性。

另请注意,以下语句无法编译:

Widget&& var1 = someWidget;

此编译错误是因为 var1 是一个 右值引用 ,因此只能使用 右值 进行初始化.然而,someWidget 是一个 lvalue 因为它有一个名字,并且没有用 std::move 标记来移动。对于要编译的语句,您可以执行以下操作之一:

  • v1 声明为 左值引用 而不是:

    Widget& var1 = someWidget;
    

    左值引用 var1可以用someWidget初始化,一个左值.

  • 标记someWidgetstd::move()一起移动:

    Widget&& var1 = std::move(someWidget);
    

    右值引用 var1可以用std::move(someWidget)初始化,一个右值.


Why does auto&& var2 not mean rvalue reference?

var2 是一个 通用引用 因为涉及类型推导。因此,var2 将成为左值引用或右值引用,具体取决于它的初始化方式(var2 将始终是引用)。

auto&& var2 = var1; 中的 auto 推导为 Widget& 因为 var1 是一个左值(即 var1 是一个命名对象而你没有对其应用 std::move())。然后,Widget& && 由于 reference collapsing 而导致 Widget&。总结一下,语句:

auto&& var2 = var1;

类型推导后变为:

Widget& var2 = var1;

所以var2实际上是一个左值引用。


如果你想让var2成为一个右值引用,你可以将std::move()应用到初始化对象:

auto&& var2 = std::move(var1);

类型推导后,结果为:

Widget&& var2 = var1;

var2 在这种情况下是右值引用。