Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么汽车和娱乐公司&;var2不表示右值引用?_C++_C++11_Auto_Rvalue Reference_Forwarding Reference - Fatal编程技术网

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
indcates
var1
是对
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;