你不可以做这个:&reinterpret_cast<PunnerToUInt32*>(&x)
规则关于reinterpret_cast state:
当指向动态类型为的对象的指针或引用时DynamicType
is reinterpret_cast
(或 C 风格转换)到不同类型对象的指针或引用AliasedType
,强制转换始终会成功,但如果满足以下条件之一,则生成的指针或引用只能用于访问对象:
-
AliasedType
是(可能符合简历要求)DynamicType
-
AliasedType
and DynamicType
都是(可能是多级的,可能在每个级别都有 cv 限定的)指向同一类型的指针T
-
AliasedType
是(可能是 cv 限定的)有符号或无符号变体DynamicType
-
AliasedType
是聚合类型或联合类型,它将上述类型之一保存为元素或非静态成员(递归地包括子聚合的元素和所包含联合的非静态数据成员):这使得可以安全地获取给定指向其非静态成员或元素的指针,指向结构或联合的可用指针。
-
AliasedType
是(可能是 cv 限定的)基类DynamicType
-
AliasedType
is char
or unsigned char
:这允许检查任何对象的对象表示作为数组unsigned char
因为这些都不适合组合DynamicType
being float
and AliasedType
being PunnerToUInt32
该指针可能无法用于访问您正在执行的操作的对象。使行为未定义。
欲了解更多信息,请参阅:为什么在相同大小的类型之间进行强制转换时,reinterpret_cast 不强制使用 copy_n?
EDIT:
Breaking down the 4th bullet int bite size chunks yields:
- "
AliasedType
"
这里取为PunnerToUInt32
-
“是聚合类型还是联合类型”
PunnerToUInt32
符合资格,因为它符合资格聚合类型:
- 数组类型
- class type (typically,
struct
or union
), that has
- 没有私有或受保护的非静态数据成员
- 没有用户提供的构造函数,包括从公共基类继承的构造函数(允许显式默认或删除的构造函数)
- 没有虚拟、私有或受保护的基类
- 没有虚拟成员函数
“它将上述类型之一保存为元素或非静态成员(递归地包括子聚合的元素和所包含联合的非静态数据成员)”
Again PunnerToUInt32
因其资格float fl
member
- “这使得获得指向结构或联合的可用指针变得安全”
这是最终正确的部分AliassedType
is a PunnerToUInt32
- “给定一个指向其非静态成员或元素的指针”
这是一种违规行为,因为DynamicType
这是x
不是以下成员PunnerToUInt32
因为违反了第5部分,对此指针进行操作是未定义的行为。
如果您喜欢一些推荐读物,您可以查看空基地优化如果没有,我会在这里给你主要的相关性:
标准布局类型需要空基优化,以维持指向标准布局对象的指针的要求,使用reinterpret_cast
, 指向其初始成员
Thus you could exploit reinterpret_cast
's 4th bullet by doing this:
PunnerToUInt32 x = {13, 42.0F};
auto y = reinterpret_cast<PunnerToUInt32*>(&x.ui32);
Live Example