C++ 为什么汽车和娱乐公司&;var2不表示右值引用?
为什么C++ 为什么汽车和娱乐公司&;var2不表示右值引用?,c++,c++11,auto,rvalue-reference,forwarding-reference,C++,C++11,Auto,Rvalue Reference,Forwarding Reference,为什么auto&&var2在下面的代码中不表示右值引用 如果能在这个问题上得到一些帮助,我将不胜感激 Widget&& var1 = someWidget; // here, “&&” means rvalue reference auto&& var2 = var1; // here, “&&” does not mean rvalue reference 既然Widget&&var1是一个右
auto&&var2
在下面的代码中不表示右值引用
如果能在这个问题上得到一些帮助,我将不胜感激
Widget&& var1 = someWidget; // here, “&&” means rvalue reference
auto&& var2 = var1; // here, “&&” does not mean rvalue reference
既然Widget&&var1
是一个右值引用,为什么它不是右值
为什么
auto&&var2=var1代码>不表示右值引用
既然Widget&&var1
是一个右值引用,为什么它不是右值
someWidget
、var1
和var2
都有一个名称,因此,无论声明的类型如何,它们都是左值
术语rvalue reference是关于引用的类型,var1
,而术语rvalue是关于表达式var1
的值类别的:
var1
声明为Widget&&var1
是对Widget
的引用,特别是对Widget
(即Widget&
)的右值引用–这是var1
的类型,它是一个引用。引用类型告诉您如何初始化引用:右值引用只能用右值初始化,而非常量左值引用只能用左值初始化
- 在表达式中使用
var1
时(不使用std::move
标记),则var1
是左值,因为它有一个名称–这是var1
的值类别,它是表达式var1
与其类型正交的属性
还请注意,以下语句未编译:
Widget&& var1 = someWidget;
此编译错误是因为var1
是右值引用,因此只能用右值初始化。但是,someWidget
是一个左值,因为它有一个名称,并且它没有标记为移动的std::move
。要编译语句,您可以执行以下操作之一:
- 将
v1
声明为左值引用:
左值引用var1
可以用左值someWidget
初始化
- 将
someWidget
标记为使用std::move()
移动:
右值引用var1
可以用右值std::move(someWidget)
初始化
为什么auto&&var2
不表示右值引用
var2
是一个通用参考,因为其中涉及类型推断。因此,var2
将成为左值引用或右值引用,具体取决于其初始化方式(var2
将始终是引用)
auto&&var2=var1中的auto
推断为小部件&
,因为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
在本例中是一个右值引用。auto&&var2=var1代码>表示对左值的左值引用<代码>自动(&var2=std::移动(var1)代码>表示对右值的左值引用var2
本身就是一个左值std::move(var2)
是一种将左值视为右值的转换。您能详细解释一下吗?为什么var1
是左值?var1
是左值,因为它被命名为。被命名的东西是左值。@Eljay&眠りネロク 我同意你的说法,左值就是被命名的值。虽然我认为Widget&&var1
indcatesvar1
是对someWidget
的正确引用。我认为它们都是对的。所以我很困惑。@sunshilong369好吧,auto&
的术语是通用引用或转发引用。通用引用将成为左值引用或右值引用,具体取决于它分别是用左值还是右值初始化的。请注意,与普通参考的不同之处在于,发生了类型推断(即,自动
),而通用参考总是导致参考。非常感谢。是的,var1
确实有一个名字someWidget
也有一个名称,someWidget
是对象的名称。因此someWidget
是左值。由于小部件和&var1
中有一个&
,我认为var1
是对someWidget
的右值引用。我错在哪里?@sunshilong369没有矛盾,因为类型和值类别是不同的属性:someWidget
是左值。然而,它的类型是Widget&
,即右值引用。我认为您混淆了引用的类型及其值类别someWidget
、var1
和var2
都有一个名称,因此它们都是左值(它们的值类别)。“值”类别告诉您可以对这些对象执行哪些操作。例如,不能直接使用此对象初始化右值引用,而可以使用它们初始化左值引用。无论引用的类型是左值还是右值,都会告诉您如何初始化它。例如,您可以使用临时值引用初始化右值引用,但不能使用左值引用。@sunshilong369我已编辑了您的问题,以包括原始问题和后续问题。我也相应地扩展了我的答案。我希望这会有帮助。我想我基本上能理解。谢谢你的慷慨帮助。
auto&& var2 = std::move(var1);
Widget&& var2 = var1;