C++11 move 构造函数优化

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

我目前正在尝试掌握 move 构造函数的窍门。 我发现了以下内容(使用 g++ d.cpp --std=c++11 -O3 编译)

class A {
    string _x;
public:
  A(string x) { cout << "default contrsutctor: " << x << "\n"; _x = x; }
  A(const A& other) { cout << "copy contrsutctor: " << other._x << "\n"; _x = other._x;  }
  A(A&& other) { cout << "move contrsutctor: " << other._x << "\n"; _x = other._x;  }

  A foo() {
    cout << "foo: " << _x << "\n";
    return A("foo");
  }
};

int main()
{
  A a;
  A b = a;
  b.foo();
}

我希望输出:

default contrsutctor: a
move contrsutctor: a
foo: a
default contrsutctor: foo

但是输出是:

default contrsutctor: a
copy contrsutctor: a
foo: a
default contrsutctor: foo

为什么 A b = a 行没有优化为使用 move 构造函数?之后永远不会使用 a 对象,因此优化代码以使用它而不是复制构造函数是安全的。

我知道我可以用 std::move() 强制调用 move 构造函数,但我更希望在这种情况下自动发生这种情况。

最佳答案

Why isn't the A b = a line optimized to use the move constructor?

在复制构造函数和 move 构造函数中可以做的事情可能完全不同。编译器不能保证两个构造函数的结果是相同的。实现这种优化有可能改变程序的行为,从而打破 as-if rule .

您需要使用std::movea 转换为A&&:

#include <utility>
int main()
{
  A a("a");
  A b = std::move(a);
  b.foo();
}

move 构造函数的正确实现应该是:

A(A&& other)
: _x(std::move(other._x))
{}

A b = std::move(a); 行之后,a 应该是“空的”。在这种情况下,a._x 将为空。 正如@TonyD 在评论中指出的那样,a._str 可能处于未指定但有效的状态( move constructor of std:string)。在此行之后应谨慎使用 a

关于C++11 move 构造函数优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22982416/

相关文章:

function - 命名空间::function cannot be used as a function

c++ - 在 C++ 中使用的奇怪声明

c++ - 转换为 `const Y` 不适用于 clang 上的 `R&&`

c++ - 使用相同的前一个词和相同的后一个词读取不同的 QStrings? QString::indexOf

c++ - C++中的算术溢出添加了2个SWORD

c++ - std::promise 能否知道相应的 std::future 已取消等待?

c++ - 左值引用限定函数可以直接在右值引用限定函数中使用吗?

c++ - 回退到复制构造函数不起作用?

c++ - 从 C/C++ 调用 Prolog 时将事实传达给 Prolog(不使用断言)

java - opencv和python——激光曲线检测