Что касается 1 («деструктор по умолчанию»), это просто потому, что memcpy
нового объекта в существующую переменную не вызовет деструктор того, что он перезаписывает, поэтому, если класс зависит от чего-либо в этом деструкторе, его ограничения могут быть нарушен.
Что касается 2 («нет виртуальных функций»), вероятно, причина в том, что когда происходит нарезка объекта, нарезанный объект должен правильно функционировать как объект базового класса.
Представьте себе базовый и производный класс таким образом:
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>
было истинным, вы могли бы memcpy
из этой переменной в другой Base
объект w
(это скопировало бы b
и vtable
). Если бы вы сейчас позвонили w.f()
, вы бы позвонили (через виртуальную таблицу) Derived::f()
. Что, конечно, было бы неопределенным, поскольку w.d
не имеет выделенного хранилища.
Это также может составлять 3 («нет виртуальных базовых классов»), но, поскольку я практически никогда не использую виртуальные базовые классы, я уступлю их кому-то более знакомому с ними.
person
Toby Speight
schedule
15.07.2015
is_trivially_copyable
имеет кmemcpy
? - person 101010   schedule 15.07.2015