考虑以下类。如果我自己实现移动构造函数如下,为什么 bar 成员 b
不是移动而是复制?但是如果我使用默认的移动构造函数,那么 b
就会被移动。为什么 b(rhs.b)
不调用 bar(bar&&)
?
我使用 g++ 9.2.1 和 --std=c++11。
class bar {
public:
bar() { cout << "bar constructor" << endl; }
bar(const bar& rhs) { cout << "bar copy constructor" << endl; }
bar(bar&& rhs) { cout << "bar move constructor" << endl; }
};
class foo {
bar b;
public:
foo() { cout << "foo constructor" << endl; }
foo(const foo& rhs) { cout << "foo copy constructor" << endl; }
// foo(foo&& rhs) = default;
foo(foo&& rhs) : b(rhs.b) { cout << "foo move constructor" << endl; } // my version
// ^^^^^^^^
};
foo f;
foo g = std::move(f);
最佳答案
Why
b(rhs.b)
doesn't callbar(bar&&)
?
因为 rhs.b
是一个左值,右值引用不绑定(bind)到左值。结果——并且因为左值引用确实绑定(bind)到左值——重载bar(const bar&)
,即复制构造函数,被选中而不是bar(bar&&)
.
为了选择移动构造函数,您需要标记rhs.b
作为“可移动”与(<utility>
) std::move()
初始化时 foo
的 b
成员:
foo(foo&& rhs): b(std::move(rhs.b)) { /* ... */ }
^^^^^^^^^
这是一个转换表达式 rhs.b
的转换到 xvalue,即 rvalue,它绑定(bind)到 rvalue 引用。所以,这次选择了移动构造函数。
But if I use the default move constructor, then
b
is moved.
默认移动构造函数执行成员移动。
关于c++ - 为什么不调用成员变量的移动构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64348265/