Можно ли использовать is_trivially_copy_assignable и is_trivially_copy_constructible в целях оптимизации?

Кажется, что значения не безопасно копировать с 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).

0

Решение

Интересно, какова цель типа черт 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 небезопасный.

2

Другие решения

Конечно. Можно написать шаблон векторного класса, который использует это и вызывает std :: memcpy в своем конструкторе копирования, если это безопасно. Я полагаю, что, по крайней мере, одна реализация std :: copy использует аналогичную оптимизацию для случая, когда итераторы имеют тип T *, а T легко копируется.

1

Я предполагаю, что это так же, как любой другой придира в стандарте. Где-то там Джо и Джейн будут говорить о том, что символ 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 (опять же, о которой я бы действительно заботился).

0
По вопросам рекламы [email protected]