【问题标题】:is_trivially_copyable behaves differently between the constructor I implemented and the defaultis_trivially_copyable 在我实现的构造函数和默认构造函数之间的行为不同
【发布时间】:2022-01-20 05:51:46
【问题描述】:

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++ templates


【解决方案1】:

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

简单的复制构造函数 如果满足以下所有条件,则类 T 的复制构造函数是微不足道的:

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

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-23
      • 2016-03-24
      • 1970-01-01
      • 2020-05-14
      • 2016-02-08
      • 1970-01-01
      相关资源
      最近更新 更多