[英]Why can't we put into initializer of T&& a variable of T& or T?
我正在寻找描述该事实的规范性参考。 我正在尝试以下方法:
#include <iostream>
int z = 4;
int &a = z;
int &&b = a; //error: rvalue reference to type 'int'
//cannot bind to lvalue of type 'int'
int main()
{
}
#include <iostream>
int z = 4;
int &a = z;
int &&b = z; //error: error: rvalue reference to type 'int'
//cannot bind to lvalue of type 'int'
int main()
{
}
我已经阅读了8.3.2节,但是找不到任何描述。
关于右值引用的一种有用的直觉是,它们传达了所引用对象的部分“所有权”-右值引用所引用的对象将无法通过其他任何方式进行访问,因此您可以自由地修改对象(窃取内存)分配它是常见的情况),而不会“让”其他可能以其他方式引用该对象的人感到惊讶。 右值引用的全部要点是基于“移动”的语义,您可以在其中移动和回收资源(而不是分配新资源)。
这说明了上面的示例为什么是错误的。 如果允许的话
int z;
int &&b = z;
那么您将遇到一个情况,即右值引用(b)所引用的对象仍可以通过其他名称(z)访问。 如果您希望做到这一点,则需要明确地做到这一点
int z;
int &&b = std::move(z);
在这种情况下,您是说(有效)“在此之后,我不在乎'z'这个名称”。 超出范围时,编译器仍会跟踪它以清除任何(剩余)资源,但是程序并不关心它或它的值。 对于int
对象,没有任何其他资源可以窃取/移动,因此这一切都毫无意义。 另一方面,对于像集合这样的复杂对象,这可以显着提高性能。
首先,您必须移动对象以获得右值:
int &&b = std::move(z);
您可以这样想:如果发生移动, z
丢失其状态并将其交给b
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.