std :: is_trivially_copyable要求

Ofe*_*lon 2 c++ type-traits c++11

c ++标准(和几个SO 答案)声明要符合条件is_trivially_copyable<T>,类型T必须具有:

  1. 默认的析构函数,
  2. 没有虚拟功能,
  3. 没有虚拟基类.

(这些不是唯一的要求,但问题仅针对这些问题)

有人可以解释为什么?我没有看到违反这3个中的任何一个如何使得Tmemcpy不安全.

Tob*_*ght 5

关于1("一个默认的析构函数"),它只是因为memcpy一个现有变量的新对象不会调用它被覆盖的析构函数,因此如果该类依赖于该析构函数中的任何内容,则可能违反其约束.

关于2("无虚函数"),推理可能是当对象切片发生时,切片对象必须正确地作为基类对象.

想象一下基类和派生类:

class Base {
    int b;
    virtual void f() { ++b; }
}

class Derived : public Base {
    int d;
    void f() override { ++d; }
}
Run Code Online (Sandbox Code Playgroud)

现在假设您有一个实际引用对象的Base&变量.如果是真的,你可以从这个变量到另一个对象(这将复制和).如果你现在打电话,你会打电话(通过vtable).这当然是未定义的,因为没有分配存储空间.vDerivedstd::is_trivially_copyable<Base>memcpyBasewbvtablew.f()Derived::f()w.d

这也可能是3("没有虚拟基类"),但由于我几乎从不使用虚拟基类,我会推荐给更熟悉它们的人.

  • *"你可以从这个变量`memcpy`到另一个Base对象`w`"*这不是[basic.types] p2允许你做的事情.它特别限制了`memcpy`保证完成对象. (2认同)