Я понимаю, что is_pod
является достаточным условием для того, чтобы тип был memcpy
-able, но для has_trivial_destructor
также достаточен для этой цели? Если нет, то почему?
Могу ли я memcpy() любой тип, который имеет тривиальный деструктор?
Ответ 1
Нет. Требование состоит в том, чтобы тип был тривиально скопируемым (§3.9/2), который имеет еще несколько требований, например, отсутствие нетривиального конструктора копии (§ 9/6).
Тривиально-скопируемый класс - это класс, который:
- нет нетривиальных конструкторов копирования (12.8),
- нет нетривиальных конструкторов перемещения (12.8),
- нет нетривиальных операторов присваивания копий (13.5.3, 12.8),
- нет нетривиальных операторов присваивания перемещения (13.5.3, 12.8) и
- имеет тривиальный деструктор (12.4).
Итак, вы должны использовать is_trivially_copyable
.
Ответ 2
Недостаточно, чтобы объект имел тривиальный деструктор. Он также должен иметь тривиальные операции копирования. Например, объект может поддерживать указатели на внутренние буферы. Нет необходимости уничтожать что-либо, но копирование должно было бы создать указатели в скопированном объекте, потому что они в противном случае указывали бы на буфер исходного объекта.
Ответ 3
Хотя на практике это обычно редко, может быть ситуация, когда класс имеет нетривиальный конструктор копирования вместе с тривиальным деструктором. Рассмотрим класс со статической переменной-членом, которая просто подсчитывает, сколько раз класс был скопирован. Если вы memcpy
, то счетчик будет неточным.
Ответ 4
Мне кажется, что класс с простым указателем будет квалифицироваться как has_trivial_destructor
, но вы обычно хотите сделать глубокую копию, тогда как memcpy
создаст мелкую копию.