std::move on 一个已经是 T&& 的变量

std::move on a variable which already is T&&

本文关键字:变量 on move std 一个      更新时间:2023-10-16

在"如何:编写移动构造函数"页面上,Microsoft有一个关于如何编写移动构造函数的示例。它本质上是这样的形式:

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

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

命名的右值引用是左值。未命名的右值引用是右值这对于理解为什么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