![](/img/trans.png)
[英]Is it useless to declare a local variable as rvalue-reference, e.g. T&& r = move(v)?
[英]Binding rvalue-reference to a local variable in VC++
我正在使用VC ++ 2012运行以下代码:
#include <utility>
struct A
{
int* m_p;
A() { m_p = new int; }
~A() { delete m_p; }
A(const A& otherA)
{
m_p = new int;
// BOOM!
*m_p = *otherA.m_p;
}
};
A&& CreateA()
{
A a;
return std::move(a);
}
int _tmain(int argc, _TCHAR* argv[])
{
A a2 = CreateA();
return 0;
}
在创建a2 A的过程中,其复制ctor称为-并崩溃,因为在CreateA()中创建的源对象已被销毁。 这是标准行为吗? 这可能是编译器错误吗?
请注意,如果将a2的类型从“ A”更改为“ const A&”,则不会发生崩溃-这使人们更加怀疑它确实是一个错误。 谁能对此有所启发?
注意:我完全知道这不是rvalue-refs的预期用途,并且该示例是人为设计的。 只是希望能更好地了解这种新型行为。
您不能访问超出其范围的局部变量 。 右值引用不会改变这一点:它们仍然是引用。 所提供的代码具有未定义的行为,因为它返回对局部变量的引用,然后对其进行访问。
不要返回右值引用。 绝大多数时间都是愚蠢的。 而是返回值:
A CreateA()
{
A a;
return a; // a move here is automatic
// unless you are using a compiler with outdated rules like MSVC
//return std::move(a); // ok, poor MSVC
// alternatively:
//return A{}; //or
//return A();
}
当你写A const& a2 = CreateA();
没有崩溃,因为您实际上没有访问任何对象。 您要做的只是获取一个悬而未决的参考书。 但是,此代码的格式甚至不正确,只是因为MSVC对于引用绑定有一些过时的规则,所以恰好可以编译。
因此,基本上,这些行为是编译器错误和未定义行为的混合:)
查看代码中发生的情况:
CreateA()
被调用 A
的局部变量。 A
的对象超出范围并被销毁 a2
初始化为该函数调用中曾经存在的对象的副本 还有...那是行不通的。 您要复制的对象已消失。 未定义的行为。
不要那样做 :)
在C ++中,引用不会影响所引用对象的生存期。 没有“我要指向该对象,因此您无法销毁它!”。
切勿返回对本地对象的引用。 它不起作用,所以...只是不这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.