std::bit_cast
Определён в заголовке <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) не находится в пределах своего времени жизни, или
- имеет неопределённое значение.
| Бит в представлении значения результата является ошибочным, если он соответствует биту, для которого наименьший охватывающий объект имеет ошибочное значение. | (начиная с C++26) |
В остальном результат не содержит неопределённых или ошибочных значений.
| Для каждого бита в представлении значения результата, который является неопределённым, наименьший объект, содержащий этот бит, имеет неопределённое значение; поведение не определено, если только этот объект не имеет тип, дружественный к неинициализированным значениям. В остальном результат не содержит неопределённых значений. | (до C++26) |
| Для каждого бита
| (начиная с 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 support needs compiler magic
bit_cast(const From& src) noexcept
{
static_assert(std::is_trivially_constructible_v<To>,
"This implementation additionally requires "
"destination type to be trivially constructible");
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 | Применено к | Опубликованное поведение | Корректное поведение |
|---|---|---|---|
|
CWG 2482 (P1272R4) | C++20 | не было определено, возникнет ли UB при работе с неопределёнными битами | определено |
См. также
|
(C++23) | неявно создаёт объекты в заданной области памяти с повторно используемым представлением объекта (шаблон функции) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/numeric/bit_cast