问题描述
根据 cppreference.com,reinterpret_cast
:
通过重新解释底层位模式在类型之间进行转换.
Converts between types by reinterpreting the underlying bit pattern.
但是等等,这是一个谎言,因为它只在这些情况下有效:
But wait, that's a lie cause it only works in these cases:
当 T1
类型的对象的指针或引用是 reinterpret_cast
(或 C 风格强制转换)时,指向不同类型 的对象的指针或引用T2
,强制转换总是成功,但结果指针或引用只有在 T1
和 T2
都是标准布局类型和以下之一时才能访问为真:
T2
是对象的(可能是 cv 限定的)动态类型T2
和T1
都是(可能是多级的,可能在每一级都有 cv 限定)指向相同类型的指针T3
T2
是对象动态类型的(可能是 cv 限定的)有符号或无符号变体T2
是聚合类型或联合类型,将上述类型之一作为元素或非静态成员(递归地包括子聚合的元素和非静态数据成员)包含联合):这使得从结构的第一个成员和从联合的元素到包含它的结构/联合的转换是安全的.T2
是对象动态类型的(可能是 cv 限定的)基类T2
是char
或unsigned char
T2
is the (possibly cv-qualified) dynamic type of the objectT2
andT1
are both (possibly multi-level, possibly cv-qualified at each level) pointers to the same typeT3
T2
is the (possibly cv-qualified) signed or unsigned variant of the dynamic type of the objectT2
is an aggregate type or a union type which holds one of the aforementioned types as an element or non-static member (including, recursively, elements of subaggregates and non-static data members of the contained unions): this makes it safe to cast from the first member of a struct and from an element of a union to the struct/union that contains it.T2
is a (possibly cv-qualified) base class of the dynamic type of the objectT2
ischar
orunsigned char
When a pointer or reference to object of type
T1
isreinterpret_cast
(or C-style cast) to a pointer or reference to object of a different typeT2
, the cast always succeeds, but the resulting pointer or reference may only be accessed if bothT1
andT2
are standard-layout types and one of the following is true:
根据该列表,一个非法示例是:
According to that list an illegal example would be:
auto foo = 13LL;
auto bar = reinterpret_cast<double&>(foo);
因此,唯一可以接受的制作该演员表的方法是复制内存:
So the only acceptable way to make that cast is to copy the memory:
auto foo = 13LL;
double bar;
copy_n(reinterpret_cast<char*>(&foo), sizeof(foo), reinterpret_cast<char*>(&bar));
我的问题是,为什么 reinterpret_cast
不为我处理这个问题?还是有其他可用的东西,所以我不必跳过这个圈子?
My question is, why doesn't reinterpret_cast
handle that for me? Or is there something else available so I don't have to jump through this hoop?
推荐答案
为什么
reinterpret_cast
不为我处理?
一个原因是没有指定大小、对齐方式和位表示,因此这样的转换是不可移植的.但是,这并不能证明使行为未定义,只是实现定义的合理性.
One reason is that the size, alignment, and bit representations aren't specified, so such a conversion wouldn't be portable. However, that wouldn't really justify making the behaviour undefined, just implementation-defined.
通过使其未定义,允许编译器假定不相关类型的表达式不会访问同一个对象,这可以实现更好的优化.例如,在下面:
By making it undefined, the compiler is allowed to assume that expressions of unrelated types don't access the same object, which can allow better optimisation. For example, in the following:
int & i = something();
float & f = something_else();
const int i1 = i;
f = 42;
const int i2 = i;
编译器可以假设 i1
和 i2
都具有相同的值(i
通过分配给 f
),并将它们优化为单个常量.打破假设将导致未定义的行为.
the compiler can assume that i1
and i2
both have the same value (i
being unchanged by the assignment to f
), and optimise them into a single constant. Breaking the assumption will then cause undefined behaviour.
或者还有其他可用的东西,所以我不必跳过这个圈子?
Or is there something else available so I don't have to jump through this hoop?
复制字节是将一个对象类型重新解释为不相关类型的唯一明确定义的方法.
Copying the bytes is the only well-defined way to reinterpret one object type as an unrelated type.
使用 reinterpret_cast
或联合的别名有时可能会起作用(假设大小等匹配),但如果优化器对未定义的行为过于聪明,则可能会绊倒您.
Aliasing with reinterpret_cast
or a union might work sometimes (assuming the size etc. match), but might trip you up if the optimiser gets too clever with undefined behaviour.
这篇关于为什么不 reinterpret_cast 强制 copy_n 用于相同大小类型之间的强制转换?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!