std ::移动一个已经是T&&的变量

时间:2013-07-30 14:09:41

标签: c++ c++11

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

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

我试过了,std::move确实需要,但为什么呢?我认为唯一的举动就是转换为T&&。但lhs已经是MyClass&&类型,不是吗?

1 个答案:

答案 0 :(得分: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本身也应该像rvalue一样绑定是很合理的,也就是说, 应该调用X(X&& rhs);

允许将移动sematics默认应用于具有名称的内容,如

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

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

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

  

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

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