我目前正在尝试掌握 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::move
将a
转换为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);
行之后, 正如@TonyD 在评论中指出的那样,a
应该是“空的”。在这种情况下,a._x
将为空。a._str
可能处于未指定但有效的状态( move constructor of std:string)。在此行之后应谨慎使用 a
。
关于C++11 move 构造函数优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22982416/