[英]move semantics and Lifetime of variables when binding lvalue to rvalues reference
只是为了确保能够很好地理解引擎盖下的内容......问题在代码中作为注释
void test(int && val)
{
val=4;
}//val is destroyed here ?
int main()
{
int nb;
test(std::move(nb));
//undefined behavior if I reference here nb ?
std::cout << nb;
nb=5;
std::cin.ignore();
}
你必须明白,对某些东西的右值引用并没有神奇地移动这个值。 它所做的只是使对非临时对象的非const引用成为可能。
在您的示例中,此引用与普通引用没有区别,因为您此处没有任何临时值。 你是必须让“移动”发生的人。
例如,如果你定义你的int是空的,当它的值为0
,并且你编写一个带有右值引用的函数,使用它并将传递的值设置为0
,那么你将之前的值“移动”出你的int 。 调用此函数后,它将包含0
。 但那是因为你这样定义了它。
现在,对于int来说这没有多大意义,但想象一下你正在处理一个指向大块内存的指针。
移动的值保留在有效但未指定的状态。 这基本上意味着,据我所知,它可能包含任何值,但它必须包含一些值,并且访问它是合法和定义的行为。
这不是未定义的行为,因为您实际上从未在函数内部移动val
。 std::move
只是将nb
变为右值。 这实际上只有在你有其他模糊的test
重载时才有意义。
//val is destroy here ?
答案就像参数类型是const int& val
。
//undefined behavior if I reference here nb ?
不会。但是没有指定打印出的值。 这与“未定义的行为”不同,这意味着任何事情都可能发生。 如果它是未定义的行为,则意味着您的磁盘可能会被重新格式化。
当你编写一个关心复制它的成本的新类时,rvalue引用对你很有用,并且你想编写一个移动构造函数。
使用别人的移动构造函数(只要它设计得很好)对你来说几乎是不可见的。
例如, 何时添加移动构造函数和移动赋值运算符真的会有所不同?
因此,如果您想要探索移动语义,我建议您使用移动构造函数构建一些示例代码。
有关std :: move的详细解释,请参阅此处 。 除非您不开始使用移动构造函数,否则您将无法有效地使用此新功能。 此外,我认为复制没有开销的原始类型没有任何意义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.