14

How to: Write a Move Constructor页面上Microsoft 有一个关于如何编写移动构造函数的示例。它本质上是以下形式:

MyClass::MyClass(MyClass&& lhs)
{
    *this = std::move(lhs);
}

我已经尝试过并且std::move确实需要这里,但是为什么呢?我认为 move 所做的唯一一件事就是转换为T&&. 但是lhs已经是 typeMyClass&&了,不是吗?

4

1 回答 1

20

命名的右值引用是左值。未命名的右值引用是右值。这对于理解为什么在以下情况下需要 std::move 调用很重要:foo&& r = foo(); foo f = std::move(r);

看看这个答案:https ://stackoverflow.com/a/5481588/1394283它解释得很好。


看看这个函数:

void foo(X&& x)
{
  X anotherX = x;
  // ...
}

有趣的问题是:X的复制构造函数的哪个重载在 的主体中被调用foo?这里,x是一个声明为右值引用的变量。因此,期望它x自己也应该像右值一样绑定,也就是说, X(X&& rhs);应该被调用是很合理的。

允许将移动语义默认应用于具有名称的事物,例如

X anotherX = x;
// x is still in scope!

这将是危险的混乱和容易出错,因为我们刚刚移动的东西,即我们刚刚窃取的东西,仍然可以在后续代码行中访问。但移动语义的全部意义在于仅将其应用于“无关紧要”的地方,即我们移动的东西在移动后立即死亡并消失。

这就是为什么右值引用的设计者选择了一个比这更微妙的解决方案:

被声明为右值引用的事物可以是左值或右值。区分标准是:如果它有名字,那么它就是一个左值。否则,它是一个右值。

来源:http ://thbecker.net/articles/rvalue_references/section_05.html

于 2013-07-30T14:17:26.777 回答