为什么不调用成员变量的构造函数? [英] Why move constructor of member variable is not called?

查看:70
本文介绍了为什么不调用成员变量的构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下课程.如果我自己按照以下方式实现move构造函数,为什么酒吧成员 b 不移动而是被复制?但是,如果我使用默认的move构造函数,那么 b 会被移动.为什么 b(rhs.b)不调用 bar(bar&&)吗?

Consider the following classes. If I implement the move constructor myself as follow, why bar member b is not moved but copied? But if I use the default move constructor, then b is moved. Why b(rhs.b) doesn't call bar(bar&&) ?

我将g ++ 9.2.1与--std = c ++ 11一起使用.

I use g++ 9.2.1 with --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);

推荐答案

为什么 b(rhs.b)不调用 bar(bar&)吗?

因为 rhs.b lvalue ,并且 rvalue引用不会绑定到 lvalues .结果–因为左值引用确实绑定到左值过载 bar(const bar&),即副本,而不是 bar(bar&&).

Because rhs.b is an lvalue, and rvalue references don't bind to lvalues. As a result – and because lvalue references do bind to lvaluesthe overload bar(const bar&), i.e., the copy constructor, is selected instead of bar(bar&&).

为了选择move构造函数,您需要将 rhs.b 标记为"available for move".与(< utility> )一起使用 std ::初始化 foo b 成员时,move() :

In order to get the move constructor selected, you need to mark rhs.b as "available for moving" with (<utility>) std::move() when initializing foo's b member:

foo(foo&& rhs): b(std::move(rhs.b)) { /* ... */ }
                  ^^^^^^^^^

这是一种将表达式 rhs.b 转换为 xvalue 的转换,即 rvalue ,该绑定到>右值参考.因此,这次选择了move构造函数.

This is a cast that turns the expression rhs.b into an xvalue, i.e., an rvalue, which binds to an rvalue reference. So, the move constructor is selected this time.

但是,如果我使用默认的move构造函数,则会移动 b .

默认的move构造函数执行成员级移动.

The default move constructor performs a member-wise move.

这篇关于为什么不调用成员变量的构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆