Я понимаю, что is_pod
является достаточным условием для того, чтобы тип мог быть memcpy
, но достаточно ли также has_trivial_destructor
для этой цели? Если нет, то почему?
Могу ли я использовать memcpy() любого типа с тривиальным деструктором?
Ответы (4)
Нет. Требование состоит в том, чтобы тип был тривиально копируемым (§3.9/2), который имеет еще несколько требований, например отсутствие нетривиального конструктора копирования (§9/6).
Тривиально копируемый класс — это класс, который:
— не имеет нетривиальных конструкторов копирования (12.8),
— не имеет нетривиальных конструкторов перемещения (12.8),
— не имеет нетривиальных копирующих операторов присваивания (13.5.3, 12.8),
- не имеет нетривиальных операторов присваивания перемещения (13.5.3, 12.8) и
— имеет тривиальный деструктор (12.4).
Поэтому вместо этого вы должны использовать is_trivially_copyable
.
is_trivially_copyable
, похоже, широко не задокументировано, у вас есть ссылка? Неважно, нашел это здесь: en.cppreference.com/ w/cpp/types/is_tribuly_copyable
- person Mark Ransom; 16.08.2012
is_copy_constructible<T>
, потому что это ловит удаленные конструкторы копирования. Я чувствую, что, хотя memcpy может иметь смысл подорвать частный тривиальный ctor копирования (в конце концов, это может быть автор класса, которым memcpy их), удаленный тривиальный ctor копирования не имеет смысла подрывать memcpy IMHO. Попытка memcpy их как более оптимизированную версию алгоритмов, таких как std::copy, должна потерпеть неудачу для удаленных копий IMHO.
- person Johannes Schaub - litb; 19.08.2012
Недостаточно, чтобы объект имел тривиальный деструктор. Он также должен иметь тривиальные операции копирования. Например, объект может поддерживать указатели на внутренние буферы. Нет необходимости что-либо уничтожать, но при копировании потребуется настроить указатели в копируемом объекте, потому что в противном случае они указывали бы на буфер исходного объекта.
Хотя на практике это редкость, может возникнуть ситуация, когда класс имеет нетривиальный конструктор копирования вместе с тривиальным деструктором. Рассмотрим класс со статической переменной-членом, которая просто подсчитывает, сколько раз класс был скопирован. Если вы memcpy
сделаете это, счетчик будет неточным.
shared_ptr<>
. Компилятор может опустить копии shared_ptr
, но это не приведет к утечке памяти.
- person MSalters; 16.08.2012
Мне кажется, что класс с простым указателем будет квалифицироваться как has_trivial_destructor
, но обычно вы хотите сделать глубокую копию, тогда как memcpy
создаст поверхностную копию.
is_trivially_destructible<T>::value
равно true
, то memcpy
ing a T
четко определено.
- person GManNickG; 16.08.2012
is_trivially_destructible
. - person GManNickG   schedule 16.08.2012has_trivial_destructor
были в TR1 и, вероятно, в некоторых более ранних черновиках, но позже переименованы. Я думаю, что GCC 4.6 по-прежнему поставлял трейтыhas_blah_blah
вместо версийis_blah_blah
. - person R. Martinho Fernandes   schedule 16.08.2012