c++ - 为什么不调用成员变量的移动构造函数?

标签 c++ c++11 rvalue lvalue move-constructor

考虑以下类。如果我自己实现移动构造函数如下,为什么 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 call bar(bar&&) ?

因为 rhs.b是一个左值右值引用不绑定(bind)到左值。结果——并且因为左值引用确实绑定(bind)到左值——重载bar(const bar&) ,即复制构造函数,被选中而不是bar(bar&&) .

为了选择移动构造函数,您需要标记rhs.b作为“可移动”与(<utility>) std::move() 初始化时 foob成员:

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/

相关文章:

c++ - 使用多个纹理将纹理分配给对象

c++ - C++中有便利构造函数吗?

c++ - 为什么使用 push_back() 分配时 vector 元素的地址不连续?

c++ - 虚拟多重继承 - 最终覆盖

c++ - 从通过 std::async 启动的函数抛出的异常会发生什么

c++ - 为什么 char 数组不打印值?

c++ - 实现 move 构造函数

c++ - 右值引用被视为左值?

c++ - 为什么 C++ 不支持动态数组的基于范围的 for 循环?

c++ - 检查所有类型 T 的参数包