Кажется, что значения не безопасно копировать с memcpy
если тип не является тривиально копируемым, то есть удовлетворяет std::is_trivially_copyable
тип черта. Интересно, какова цель типа черт std::is_trivially_copy_assignable
, std::is_trivially_copy_constructible
, std::is_trivially_move_assignable
а также std::is_trivially_move_constructible
если вы не можете использовать их для инициализации или назначения с memcpy
, Разрешают ли они другие оптимизации?
Мне также интересно, почему стандарт требует тривиального деструктора для значений для копирования с memcpy
, (Тривиальный деструктор действительно упрощает физическое перемещение значения в памяти, но, по-видимому, это не является принципиально необходимым для простого дублирования значения с memcpy
).
Интересно, какова цель типа черт
std::is_trivially_copy_assignable
,std::is_trivially_copy_constructible
,std::is_trivially_move_assignable
а такжеstd::is_trivially_move_constructible
если вы не можете использовать их для инициализации или назначения сmemcpy
Они говорят вам свойства типа, разве не достаточно оснований для существования?
У вас может быть тип, который имеет тривиальный конструктор копирования, но нетривиальный конструктор перемещения, поэтому он не будет квалифицироваться как тривиально копируемый тип, но будет тривиально копируемым-конструируемым.
При использовании такого типа вы можете использовать SFINAE или другой статический полиморфизм, чтобы включить / отключить определенные операции, если они не гарантированно являются тривиальными. Например, представьте шаблон класса TrivialPair<A,B>
который может объявить свой конструктор перемещения как удаленный, если A
а также B
не тривиально двигаться конструктивно, и аналогично для других операций. Это будет означать, что TrivialPair
поддерживает только те операции, которые A
а также B
оба поддерживают и которые не вызывают никаких нетривиальных функций.
Мне также интересно, почему стандарт требует тривиального деструктора для значений для копирования с
memcpy
Под «тривиально копируемым» можно понимать, что тип — это просто набор байтов, то есть просто данные, которые можно безопасно и без изменения значения скопировать в другое место в памяти. Если тип имеет нетривиальный деструктор, то это не просто набор байтов, он имеет некоторое дополнительное поведение, которое компилятор не понимает, и которое может сделать использование memcpy
небезопасный.
Конечно. Можно написать шаблон векторного класса, который использует это и вызывает std :: memcpy в своем конструкторе копирования, если это безопасно. Я полагаю, что, по крайней мере, одна реализация std :: copy использует аналогичную оптимизацию для случая, когда итераторы имеют тип T *, а T легко копируется.
Я предполагаю, что это так же, как любой другой придира в стандарте. Где-то там Джо и Джейн будут говорить о том, что символ 8 бит, а Боб будет кричать о том, что стандарт говорит, что на самом деле «8 или БОЛЬШЕ бит!» На следующий день они предпримут хакерские удары по типам, скопировав float в uint32_t и сделав немного твиддлинга, основанного на IEEE-754, и Боб снова придет, крича о том, что IEEE-754 строго не требуется, и он будет настаивать на том, что тот маленький поворот, который они совершают, может привести к тому, что какая-то теоретическая машина разрушит вселенную.
Черт возьми, Боб!
На практике совершенно очевидно, что std :: is_trivially_copy_assignable означает, что выражение «A = B» будет просто преобразовано в memcpy (), поэтому продолжайте и пользуйтесь. Конечно, там может быть какая-то неясная реализация, которая изо всех сил старается показать вам, когда вы используете memcpy () тип, который не является строго std :: is_trivially_copyable, и я уверен, что Боб, вероятно, является автором указанной реализации , а тебе правда все равно?
Это только мое предположение, заметьте. У меня есть некоторый умеренный опыт в этой области, но я ни в коем случае не эксперт мирового уровня по мелочам C ++. Если я ошибаюсь (на практике, а не только в теории), пожалуйста, дайте мне знать. Я также хотел бы видеть машину с CHAR_BIT> 8 (которая мне действительно нужна) или машину с плавающими не IEEE-754 (опять же, о которой я бы действительно заботился).