首页 > 解决方案 > 为什么 auto&& var2 不暗示右值引用?

问题描述

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

对于这个问题,我将不胜感激。

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

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

为什么不auto&& var2 = var1;意味着右值引用?

标签: c++c++11autorvalue-referenceforwarding-reference

解决方案


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

someWidget, var1, 并且var2都有一个名字,因此,无论它们声明的类型如何,它们都是左值。

术语右值引用与引用的类型有关var1而术语值与表达式的值类别var1有关:

  • var1声明为Widget&& var1是对 的引用Widget特别是对(ie, ) 的右值引用——这是 的类型,它是一个引用。引用类型告诉你如何初始化引用:右值引用只能用右值初始化,而非左值引用只能用左值初始化。WidgetWidget&&var1const

  • var1在表达式中使用时(不使用 标记std::move),thenvar1是一个左值,因为它有一个名称——这是 的值类别,它是与其类型正交var1的表达式的属性。var1

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

Widget&& var1 = someWidget;

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

  • 改为声明v1左值引用:

    Widget& var1 = someWidget;
    

    左值引用 var1可以用左someWidget初始化。

  • someWidget移动标记std::move()

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

    rvalue 引用 var1可以用rvaluestd::move(someWidget)初始化。


为什么不auto&& var2意味着右值引用?

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

autoinauto&& var2 = var1;推断为因为Widget&var1一个左值(即,var1是一个命名对象并且您尚未应用std::move()它)。然后,由于参考崩溃Widget& &&导致结果。综上所述,声明:Widget&

auto&& var2 = var1;

类型推演后变为:

Widget& var2 = var1;

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


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

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

扣除类型后,结果为:

Widget&& var2 = var1;

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


推荐阅读