在这种情况下是否会移动值

时间:2017-12-20 07:18:03

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

请考虑以下代码段:

class Bar {...};
class Foo {
  public:
    Foo(const Bar& bar): bar_(bar) {}
  private:
    Bar bar_;
};

int main() {
    Foo foo({...});  // Passing an rvalue Bar object here.
}

问题:我生成的对象是否会被复制到Foo的构造函数中,还是会被移动?更准确地说,以下哪一项是正确的?

  • 将永远复制。
  • 它会一直被移动(我很确定不是这样)。
  • 这是未指明的行为。

1 个答案:

答案 0 :(得分:4)

  

它将一直被复制。

您创建的rvalue绑定到const左值引用。但即使它绑定到右值引用,也可以从左值(bar_(bar))构造bar。 绑定到引用的对象的值类别没有实际意义,重要的是引用本身的值类别。就像已经提到的那样,表达式bar是一个左值。

作为一般的,有点粗略的经验法则,每个表达某事物的表达都是左值。

如果你想在一个构造函数中支持移动和副本,那么前进的方法是:

Foo(Bar bar): bar_(std::move(bar)) {}

现在bar可以通过移动副本来构建,具体取决于源,并且您的成员是从您可以安全移出的对象构造的。这当然总是会产生额外的举动。如果你想避免它,那么需要两个c'tors:

Foo(const Bar& bar): bar_(bar) {}
Foo(Bar&& bar): bar_(std::move(bar)) {}