std::bit_cast

来自cppreference.com
< cpp‎ | numeric
定义于头文件 <bit>
template< class To, class From >
constexpr To bit_cast(const From& from) noexcept;
(C++20 起)

通过转译 from 的对象表示获得 To 类型值。返回的 To 对象值表示中的每位都等于 from 的对象表示中的对应位。返回的 To 对象中的填充位的值未指定。

若无 To 类型值对应产生的值表示,则行为未定义。若有多个这种值,则产生哪个值是未指定的。

此重载仅若 sizeof(To) == sizeof(From)ToFrom 两者都是可平凡复制 (TriviallyCopyable) 类型才参与重载决议。

此函数模板为 constexpr ,若且唯若 ToFromToFrom 的所有子对象的类型都:

  • 不是联合体类型;
  • 不是指针类型;
  • 不是指向成员指针类型;
  • 不是 volatile 限定类型;且
  • 无引用类型的非静态数据成员。

[编辑] 返回值

值表示描述如上的 To 类型对象。

[编辑] 注意

大多数情况下不应该用指针或引用类型间的 reinterpret_cast (或等价的显式转型)转译对象表示,因为类型别名使用规则

std::bit_cast 前,需要翻译对象表示为另一类型的对象表示时,能使用 std::memcpy

template <class To, class From>
typename std::enable_if<
    (sizeof(To) == sizeof(From)) &&
    std::is_trivially_copyable<From>::value &&
    std::is_trivial<To>::value,
    // 此实现要求 To 可平凡默认构造
    To>::type
// constexpr 支持需要编译器魔法
bit_cast(const From &src) noexcept
{
    To dst;
    std::memcpy(&dst, &src, sizeof(To));
    return dst;
}

[编辑] 示例

#include <cstdint>
#include <bit>
#include <iostream>
 
constexpr double f64v = 19260817.0;
constexpr auto u64v = std::bit_cast<std::uint64_t>(f64v);
 
constexpr std::uint64_t u64v2 = 0x3fe9000000000000ull;
constexpr auto f64v2 = std::bit_cast<double>(u64v2);
 
int main()
{
    std::cout
        << std::fixed <<f64v << "f64.to_bits() == 0x"
        << std::hex << u64v << "u64\n";
 
    std::cout
        << "f64::from_bits(0x" << std::hex << u64v2 << "u64) == "
        << std::fixed << f64v2 << "f64\n";
}

可能的输出:

19260817.000000f64.to_bits() == 0x41725e5910000000u64
f64::from_bits(0x3fe9000000000000u64) == 0.781250f64