Могу ли я memcpy() любой тип, который имеет тривиальный деструктор?

Я понимаю, что is_pod является достаточным условием для того, чтобы тип был memcpy -able, но для has_trivial_destructor также достаточен для этой цели? Если нет, то почему?

Ответ 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 создаст мелкую копию.