yur*_*hek 15 c++ strict-aliasing language-lawyer type-punning
由于C++ 11 std::complex<T>[n]保证T[n*2]具有可定义的值,因此具有良好定义的值.这正是人们对任何主流架构的期望.对于我自己的类型,这种保证是否可以通过标准C++实现,struct vec3 { float x, y, z; }或者只有在编译器的特殊支持下才能实现?
TL; DR:编译器必须检查reinterpret_casts并确定涉及的(标准库)特化std::complex.我们不能一致地模仿语义.
我认为很明显将三个不同的成员视为数组元素是行不通的,因为指向它们的指针算法受到极大的限制(例如,添加1会产生指针过去的结尾).
所以我们假设vec3包含一个由三个ints组成的数组.即使这样,reinterpret_cast<int*>(&v)你隐含需要的底层(在哪里v是a vec3)也不会给你一个指向第一个元素的指针.请参阅指针可互换性的详尽要求:
两个对象
a,如果符合以下情况,b则指针可互换:
它们是同一个对象,或者
一个是标准布局联合对象,另一个是该对象的非静态数据成员([class.union]),或者
一个是标准布局类对象,另一个是该对象的第一个非静态数据成员,或者,如果该对象没有非静态数据成员,则该对象的第一个基类子对象([class.mem]) ), 要么
存在一个物体
c,使得a和c是指针相互转化,和c和b是指针的互变的.如果两个对象是指针可互换的,那么它们具有相同的地址,并且可以通过a获得指向另一个指针的指针
reinterpret_cast.[ 注意:数组对象及其第一个元素不是指针可互换的,即使它们具有相同的地址. - 结束说明 ]
这是非常明确的; 虽然我们可以得到一个指向数组的指针(作为第一个成员),虽然指针 - 可互换性是可传递的,但我们无法获得指向其第一个元素的指针.
最后,即使你设法获得指向成员数组的第一个元素的指针,如果你有一个vec3s 数组,你也不能 使用简单的指针增量遍历所有成员数组,因为我们得到了指针的结尾.中间的数组.swder也没有解决这个问题,因为与指针相关联的对象不共享任何存储(cf [ptr.launder]了解具体内容).
只有在编译器的特殊支持下才能实现.
工会不会让你到那里因为常见的方法实际上有未定义的行为,虽然布局兼容的初始序列有例外,你可以通过unsigned char*一个特殊情况检查一个对象.不过就是这样.
有趣的是,除非我们假设"下面"具有广泛而无用的含义,否则该标准在技术上是矛盾的:
[C++14: 5.2.10/1]:[..]下面列出了可以使用reinterpret_cast显式执行的转换.使用reinterpret_cast不能显式执行其他转换.
complex<T>然后没有提到案例.最后,您提到的规则将在很长一段时间后推出[C++14: 26.4/4].