is_trivially_copyable 我实现的构造函数和默认构造函数的行为不同

is_trivially_copyable behaves differently between the constructor I implemented and the default

std::is_trivially_copyable有演示代码 https://en.cppreference.com/w/cpp/types/is_trivially_copyable

void test()
{
    struct A {
        int m;
        A(const A& o):m(o.m){}
    };

    struct D {
        int m;

        D(D const&) = default; // -> trivially copyable
        D(int x) : m(x + 1) {}
    };

    std::cout << std::is_trivially_copyable<A>::value << '\n';
    std::cout << std::is_trivially_copyable<D>::value << '\n';
}

A 不可复制,但 D 可以。我用默认行为实现了 A 的复制构造函数。造成差异的原因是什么?

这不是微不足道的,因为它是用户定义的。这是规则。

编译器不需要确定您的代码是否与其生成的代码相同。那是你的工作要弄清楚。 :-)

C++ 中是这样定义的: https://en.cppreference.com/w/cpp/language/copy_constructor#Trivial_copy_constructor

平凡的复制构造函数 如果以下所有条件都为真,则 class T 的复制构造函数是微不足道的:

  • 不是用户提供的(即隐式定义或 默认);
  • T没有虚成员函数;
  • T 没有虚拟基地 classes;
  • 为 T 的每个直接基选择的复制构造函数是微不足道的;
  • 为 T 的每个非静态 class 类型(或 class 类型的数组)成员选择的复制构造函数是微不足道的;

非联合的普通复制构造函数 class 有效地复制参数的每个标量子对象(包括递归地,子对象的子对象等等)并且不执行任何其他操作。但是,不需要复制填充字节,即使复制的子对象的对象表示也不需要相同,只要它们的值相同即可。

可以通过手动复制对象表示来复制 TriviallyCopyable 对象,例如std::memmove。所有与 C 语言兼容的数据类型(POD 类型)都是可平凡复制的。