Evg*_*Evg 14 c++ type-punning c++20
Timur Doumler 在他最近的演讲“现代C ++中的类型修剪”中说,由于不能从函数返回C样式的数组,std::bit_cast因此不能用于将a进行位强制float转换unsigned char[4]。我们应该使用std::memcpy或等到C ++ 23(或更高版本)后,类似的东西reinterpret_cast<unsigned char*>(&f)[i]才能被很好地定义。
在C ++ 20中,我们可以在中std::array使用std::bit_cast,
float f = /* some value */;
auto bits = std::bit_cast<std::array<unsigned char, sizeof(float)>>(f);
Run Code Online (Sandbox Code Playgroud)
而不是C样式的数组来获取float?的字节?
Tim*_*ler 15
是的,这适用于所有主要的编译器,据我观察标准可以得知,它是可移植的,并且可以正常工作。
首先,std::array<unsigned char, sizeof(float)>保证是一个聚合(https://eel.is/c++draft/array#overview-2)。由此可见,它内部恰好包含sizeof(float)多个chars(通常以a表示char[],尽管从原则上讲,该标准并未强制要求该特定实现-但它确实说元素必须是连续的),并且不能具有任何其他非静态成员。
因此,它是可复制的,并且其大小也与之匹配float。
这两个属性允许您bit_cast在它们之间。
标头
<array>定义用于存储固定大小的对象序列的类模板。数组是一个连续的容器。array<T, N>存储N类型为的元素的实例T,因此size() == N是不变的。数组是一个聚合,最多可以将
N其类型转换为的元素进行列表初始化T。数组满足容器和可逆容器(
[container.requirements])的所有要求,除了默认构造的数组对象不为空并且交换不具有恒定的复杂性。数组满足序列容器的某些要求。在此仅提供对这些表之一中未描述的对数组的操作以及存在其他语义信息的操作的描述。
该标准实际上不需要std::array拥有一个类型的公共数据成员T[N],因此从理论上讲,可能是sizeof(To) != sizeof(From)或is_trivially_copyable_v<To>。
但是,如果这在实践中不起作用,我将感到惊讶。