bit_cast
Начиная с C++20 появилась шаблонная функция
В конкретном примере переменные
Аналогичного результата можно добиться и с помощью
В отличие от альтернативных способов, шаблонная функция
Продемонстрирую проблему на примере с
Бывает и так, что изначально некоторые типы были реализованы тривиальными, но затем (в ходе доработок) потеряли такое свойство. Встроенные проверки
Нельзя назвать
Оставляйте реакции, считаете ли вы этот пост полезным для других! А мы, как и всегда, будем рады прочитать ваши комментарии и ответить вопросы 😉
#cppcore #cpp20
Начиная с C++20 появилась шаблонная функция
std::bit_cast
в заголовочном файле <bit>
. Она предоставляет возможность создавать побитовые копии объектов с другим типом:#include <bit>
double src = 42.0;
uint64_t dst = std::bit_cast<uint64_t>(src);
В конкретном примере переменные
dst
и src
имеют одинаковый размер 8 байт, поэтому их содержимое может быть интерпретировано по-разному, в зависимости от типа представления: беззнаковое целое или число с плавающей запятой.Аналогичного результата можно добиться и с помощью
union
или reinterpret_cast
. Однако, это нельзя было сделать в compile time! Функция std::bit_cast
поддерживает constexpr
выражения. Бонусом мы получаем достаточно лаконичное приведение и не нарушаем strict aliasing.В отличие от альтернативных способов, шаблонная функция
std::bit_cast
дополнительно проверяет, что исходный и целевой типы имеют одинаковый размер и могут быть тривиально скопированы. Последнее означает, что память объекта может быть просто скопирована без дополнительных действий и это будет рабочей копией. Если это не так, то такие операции могут нарушать жизненный цикл нового объекта.Продемонстрирую проблему на примере с
std::string
. Объекты данного типа, в общем случае, хранят строку где-то в другом месте, а сами выступают в роли умной оболочки (RAII). Клонирование такого объекта «в лоб» создает потенциально опасную ситуацию: два объекта будут ссылаться на один и тот же уникальный ресурс и пытаться управлять им. Например, они оба попытаются освободить ресурс. У первого объекта это получится, а у второго приведет к ошибке double free: живой пример. Отсюда и вытекает ограничение, что нельзя создавать побитовых клонов нетривиально копируемых объектов. Им необходимо обязательно вызвать конструктор копирования, который выделит собственный ресурс. Бывает и так, что изначально некоторые типы были реализованы тривиальными, но затем (в ходе доработок) потеряли такое свойство. Встроенные проверки
std::bit_cast
тут же сообщат о некорректности работы с таким типом.Нельзя назвать
std::bit_cast
оператором приведения, т.к. эта штука все таки не включена в семантику языка (в отличие от static_cast
, reinterpret_cast
и т.д.) и вынесена в пространство имен библиотеки STL. Однако её стоит упомянуть в текущем цикле статей.Оставляйте реакции, считаете ли вы этот пост полезным для других! А мы, как и всегда, будем рады прочитать ваши комментарии и ответить вопросы 😉
#cppcore #cpp20