c++标准(以及几个SO answers)指出,要符合is_trivially_copyable<T>的要求,类型T必须具有:

  • 默认的析构函数
  • 没有虚函数,
  • 没有虚拟基类。

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

    有人可以解释为什么吗?我看不到违反这3种方法如何使T数组对memcpy不安全。

    最佳答案

    关于1(“默认析构函数”),仅是因为将新对象的memcpy转换为现有变量不会调用其覆盖的析构函数,因此,如果类依赖于该析构函数中的任何内容,则其约束可能是违反了。

    对于2(“无虚函数”),可能的原因是当发生对象 slice 时, slice 的对象必须正确地充当基类对象。

    想象一下这样的基类和派生类:

    class Base {
        int b;
        virtual void f() { ++b; }
    }
    
    class Derived : public Base {
        int d;
        void f() override { ++d; }
    }
    

    现在,假设您有一个Base&变量v,它实际上引用了Derived对象。如果std::is_trivially_copyable<Base>为true,则可以将该变量中的memcpy转换为另一个Base对象w(这将复制bvtable)。如果现在要调用w.f(),则可以(通过vtable)调用Derived::f()。当然,哪一个是不确定的,因为w.d没有分配存储空间。

    这可能也占了3个(“没有虚拟基类”),但是由于我几乎从不使用虚拟基类,因此我会请更熟悉它们的人来做。

    关于c++ - std::is_trivially_copyable要求,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31424185/

    10-15 17:52