C++ 字段的复制省略

标签 c++ c++17 in-place copy-elision

我正在尝试让复制省略适用于要返回的对象的字段。

示例代码:

#include <iostream>

struct A {
    bool x;
    A(bool x) : x(x) {
        std::cout << "A constructed" << std::endl;
    }
    A(const A &other) : x(other.x) {
        std::cout << "A copied" << std::endl;
    }
    A(A &&other) : x(other.x) {
        std::cout << "A moved" << std::endl;
    }
    A &operator=(const A &other) {
        std::cout << "A reassigned" << std::endl;
        if (this != &other) {
            x = other.x;
        }
        return *this;
    }
};

struct B {
    A a;
    B(const A &a) : a(a) {
        std::cout << "B constructed" << std::endl;
    }
    B(const B &other) : a(other.a) {
        std::cout << "B copied" << std::endl;
    }
    B(B &&other) : a(other.a) {
        std::cout << "B moved" << std::endl;
    }
    B &operator=(const B &other) {
        std::cout << "B reassigned" << std::endl;
        if (this != &other) {
            a = other.a;
        }
        return *this;
    }
};

B foo() {
    return B{A{true}};
}


int main() {
    B b = foo();
    std::cout << b.a.x << std::endl;
}

我编译: g++ -std=c++17 test.cpp -o test.exe

输出:

A constructed
A copied
B constructed
1

B 是就地构建的。为什么A不是?我至少希望它是移动构造的,但它是被复制的。

有没有办法在要返回的 B 内部就地构造 A?怎么办?

最佳答案

A 构造 B 涉及复制 A - 它在您的代码中是这样说的。这与函数返回中的复制省略无关,所有这些都发生在 B 的(最终)构造中。标准中没有任何内容允许删除(如“打破假设规则”)成员初始化列表中的复制构造。请参阅[class.copy.elision]对于少数可能会违反假设规则的情况。

换句话说:创建 B b{A{true}}; 时,您会得到完全相同的输出。函数返回值同样好,但并没有更好。

如果您希望移动 A 而不是复制,则需要一个构造函数 B(A&&) (然后移动构造 a > 成员(member))。

关于C++ 字段的复制省略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59756657/

相关文章:

c# - 了解 C++ 对 Web 应用程序开发的重要性

c++ - 外部定义的函数指针作为模板参数

c++ - 如何使用 C++ 中的函数在数组中输入用户值?

python - 按条件对 numpy 数组进行就地分区

mysql 以优化的方式向大表添加多列

c++ - 相互竞争的原子操作会互相饿死吗?

c++ - 是否可以简单地复制::std::tuple-like 类模板?是否存在实现?

c++ - 在仅 header 库中拆分大文件

C++,函数指针异常错误

performance - 将所有奇数定位的元素原地移动到左半部分,偶数定位到右半部分