Namespaces
Variants

std:: bit_cast

From cppreference.net
Utilities library
Определено в заголовке <bit>
template < class To, class From >
constexpr To bit_cast ( const From & from ) noexcept ;
(начиная с C++20)

Получите значение типа To путём переинтерпретации объектного представления From . Каждый бит в представлении значения возвращаемого объекта To равен соответствующему биту в объектном представлении объекта from . Значения битов заполнения в возвращаемом объекте To не определены.

Если нет значения типа To соответствующего произведённому представлению значения, поведение не определено. Если существует несколько таких значений, какое именно значение будет произведено - не специфицировано.

Бит в представлении значения результата является неопределённым , если он

  • не соответствует биту в представлении значения From (т.е. соответствует биту заполнения), или
  • соответствует биту объекта, который (до C++26) для которого наименьший содержащий объект (начиная с C++26) не находится в пределах своего времени жизни , или
  • имеет неопределённое значение .

Бит в представлении значения результата является ошибочным если он соответствует биту, для которого наименьший содержащий объект имеет ошибочное значение .

(since C++26)


Результат не содержит никаких других неопределённых или ошибочных значений.

Для каждого бита в представлении значения результата, который является неопределённым, наименьший объект, содержащий этот бит, имеет неопределённое значение; поведение не определено, если этот объект не является типом, дружественным к неинициализированным данным .

Результат не содержит никаких других неопределённых значений.

(до C++26)

Для каждого бита b в представлении значения результата, который является неопределённым или ошибочным, пусть u будет наименьшим объектом, содержащим b :

  • Если u является типом, дружественным к неинициализированным данным , u имеет неопределённое значение, если любой из битов в его представлении значения является неопределённым, или иначе имеет ошибочное значение.
  • Иначе, если b является неопределённым, поведение не определено.
  • Иначе, поведение является ошибочным , и результат указан выше.
(начиная с C++26)

Эта перегрузка участвует в разрешении перегрузки только если sizeof ( To ) == sizeof ( From ) и оба типа To и From являются TriviallyCopyable типами.

Этот шаблон функции является constexpr тогда и только тогда, когда каждый из To , From и типы всех подобъектов To и From :

  • не является типом объединения;
  • не является типом указателя;
  • не является типом указателя на член класса;
  • не является типом с квалификатором volatile; и
  • не имеет нестатических членов данных ссылочного типа.

Содержание

Параметры

from - источник битов для возвращаемого значения

Возвращаемое значение

Объект типа To , чьё представление значения описано выше.

Возможная реализация

Для реализации std::bit_cast , игнорируя тот факт, что это constexpr , std::memcpy может быть использована, когда требуется интерпретировать представление объекта как представление другого типа:

template<class To, class From>
std::enable_if_t<
    sizeof(To) == sizeof(From) &&
    std::is_trivially_copyable_v<From> &&
    std::is_trivially_copyable_v<To>,
    To>
// поддержка constexpr требует магии компилятора
bit_cast(const From& src) noexcept
{
    static_assert(std::is_trivially_constructible_v<To>,
        "Эта реализация дополнительно требует "
        "чтобы тип назначения был тривиально конструируемым");
    To dst;
    std::memcpy(&dst, &src, sizeof(To));
    return dst;
}

Примечания

reinterpret_cast (или эквивалентное явное приведение типа ) между указателями или ссылочными типами не должно использоваться для переинтерпретации представления объекта в большинстве случаев из-за правила псевдонимов типов .

Макрос тестирования возможностей Значение Стандарт Функция
__cpp_lib_bit_cast 201806L (C++20) std::bit_cast

Пример

#include <bit>
#include <cstdint>
#include <iostream>
constexpr double f64v = 19880124.0; 
constexpr auto u64v = std::bit_cast<std::uint64_t>(f64v);
static_assert(std::bit_cast<double>(u64v) == f64v); // round-trip
constexpr std::uint64_t u64v2 = 0x3fe9000000000000ull;
constexpr auto f64v2 = std::bit_cast<double>(u64v2);
static_assert(std::bit_cast<std::uint64_t>(f64v2) == u64v2); // round-trip
int main()
{
    std::cout
        << "std::bit_cast<std::uint64_t>(" << std::fixed << f64v << ") == 0x"
        << std::hex << u64v << '\n'
        << "std::bit_cast<double>(0x" << std::hex << u64v2 << ") == "
        << std::fixed << f64v2 << '\n';
}

Возможный вывод:

std::bit_cast<std::uint64_t>(19880124.000000) == 0x4172f58bc0000000
std::bit_cast<double>(0x3fe9000000000000) == 0.781250

Отчёты о дефектах

Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены задним числом к ранее опубликованным стандартам C++.

DR Applied to Behavior as published Correct behavior
CWG 2482
( P1272R4 )
C++20 не было указано, будет ли возникать неопределенное поведение при работе с неопределенными битами указано

Смотрите также

неявно создаёт объекты в заданной области памяти с повторным использованием представления объекта
(function template)