std::bit_cast是C++20引入的类型安全位重解释工具,用于相同大小trivially copyable类型间无损比特复制,可替代reinterpret_cast+memcpy、联合体非法读取和手动memcpy;要求两类型大小相等、均为平凡可复制且启用C++20。
什么是
,它能替代哪些操作
是 C++20 引入的类型安全位重解释工具,用于在两个相同大小的类型之间无损复制底层比特模式。它不是类型转换,不调用构造函数、析构函数或转换运算符,也不涉及指针别名(因此规避了 strict aliasing 问题)。常见替代目标包括:
+
组合、联合体(
)的非法读取、以及
手动实现的位拷贝。
使用
的硬性前提和编译要求
必须满足三个条件,否则编译失败:
源类型和目标类型
必须是 trivially copyable
(例如
、
、
,但不能是含虚函数、非平凡构造/析构的类)
源类型与目标类型的
必须严格相等(
会触发
编译错误
)
必须启用 C++20 或更高标准(GCC/Clang 需
;MSVC 默认 C++17 不够,需
)
例如:
合法;
编译报错(
非 trivially copyable);
报错(
)。
典型安全用例:浮点与整数互转、
字节
序无关的序列化
最常见且推荐的用途是 IEEE 754 浮点数与对应宽度整数之间的精确位映射,比如提取 float 的符号/指数/尾数,或构建特定 bit pattern 的 float:
立即学习
“
C++免费学习笔记(深入)
”;
C函数速查手册(CHM版)
C函数速查手册(CHM版)
下载
另一个实用场景是跨平台二进制协议中避免依赖
的手动字节翻转 —— 只要两端都用
转成固定大小整数,再按需字节序处理即可。
容易忽略的陷阱:对齐、const、以及 constexpr 上下文限制
是 constexpr 函数,但有隐含约束:
若参数是 const 对象,返回值也是 const 类型(不可忽略 cv-qualifiers)
源对象必须满足其对齐要求(例如把
的首地址传给
时,该地址必须是
对齐的,否则行为未定义)
不能用于 volatile 类型(编译器拒绝)
不能在 constexpr 函数中对未初始化内存做
(如
即使不执行也会导致 constexpr 失败)
实际
编码
中,建议始终用数组或
承载原始字节,再通过
转出,这样对齐和生命周期都可控。
std::bit_caststd::bit_castreinterpret_castmemcpyunionstd::memcpystd::bit_castintfloatstd::arraysizeofstatic_assert(sizeof(T) == sizeof(U))-std=c++20/std:c++20std::bit_cast(0x3f800000) std::bit_cast(42) std::stringstd::bit_cast(1) sizeof(int) != sizeof(double)#include
#include
int main() {
float f = 3.14f;
auto bits = std::bit_cast(f); // 得到 IEEE 754 表示
std::cout << std::hex << bits << "\n"; // 输出: 4048f5c3
uint32_t pattern = 0x4048f5c3;
float restored = std::bit_cast(pattern);
// guaranteed same as original f (if no NaN/signaling bit shenanigans)
} htonlstd::bit_caststd::bit_castchar[4]std::bit_castalignof(uint32_t)std::bit_caststd::bit_cast(*reinterpret_cast(nullptr)) std::arraystd::bit_cast