为什么std :: move(arg)改变了arg参数?

时间:2017-11-04 19:12:08

标签: c++ c++11 move-semantics

有代码

string one = "one";
string two{ one };
string three{ move(one)};
cout << one  << endl;

这打印“”。这是因为调用了字符串3的移动构造函数并且窃取了它的参数值。但是,如何修改变量1?

当我们通过move(one)时,返回rvalue。并且移动构造函数从THAT rvalue窃取资源,变量one不作为引用或指针传递。那么这样的行为怎么会发生呢?

感谢答案

3 个答案:

答案 0 :(得分:2)

std::move()实际上并未改变其参数

...但确实让代码的输出“蚕食”了这个论点。因此,您的three字符串会删除one的缓冲区,并将其留空。

您还可以在网站上阅读有关std::move()的{​​{3}}(回答问题this detailed explanation)。

答案 1 :(得分:1)

在标题中,您会问:

  

为什么std::move( arg )改变arg参数?

std::move(arg)不会改变arg的内容。它只是将arg转换为右值反射。

使用

调用std::string的构造函数
string three{ move(one)};

改变了one的内容,因为它调用了&#34;移动&#34;构造

这是理想的行为。您要求编译器移动&#34;从onethree的数据。目的是蚕食one的内容并将其留在状态。当然, empty 的概念是编译器特定的。

您可以在http://www.stroustrup.com/C++11FAQ.html#rval阅读有关右值引用,移动构造函数和移动赋值运算符的更多信息。

回复:

  

当我们通过move(一)时,返回rvalue。

这是不正确的。 move(one)返回右值引用。

答案 2 :(得分:0)

  

当我们通过move(one)时,返回rvalue。并且移动构造函数从 THAT rvalue 窃取资源,变量one不作为引用或指针传递。

&#34;这是价值&#34;是one对象。因此,three会窃取one中的数据。

在这一行:

string three{move(one)};

three收到对one的右值引用,因此当它从该右值引用中窃取数据时,它会从one窃取数据,因为右值引用为< / strong> one对象。

由于one有一个名称,您可以获取其地址,因此它不是右值引用。使用std::move() 将其转换为右值引用,以便您可以从中移动它。从它移开后,其状态为未指定。对于std::string,这意味着在移动之后您无法知道它包含的内容。它可以包含任何东西。移动后它仍然是有效的std::string,但其内容未知。在您的特定编译器/库中,恰好新状态是一个空字符串。