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(т.е. он соответствует биту заполнения), или - соответствует биту объекта, который не находится в рамках своего жизненного цикла, или
- имеет неопределённое значение.
Для каждого бита в представлении значения результата, который является неопределённым, наименьший объект, содержащий этот бит, имеет неопределённое значение; поведение не определено, если этот объект не является типа unsigned char или std::byte. В противном случае результат не содержит неопределённых значений.
Эта перегрузка участвует в разрешении перегрузки только в том случае, если 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 (или эквивалентное явное преобразование) между типами указателей или ссылок не следует использовать для переинтерпретации представления объекта в большинстве случаев из-за правила алиасинга типов.
| Макросы проверки наличия функции | Значение | Std | Функция |
|---|---|---|---|
__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 | C++20 | было не определено, будет ли возникать UB при вовлечении неопределённых битов | определено |
См. также
|
(C++23) | неявно создаёт объекты в заданном хранилище с повторно использованным представлением объекта (шаблон функции) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/numeric/bit_cast