`std :: complex <T> [n]`和`T [n*2]`类型别名

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; }或者只有在编译器的特殊支持下才能实现?

Col*_*mbo 9

TL; DR:编译器必须检查reinterpret_casts并确定涉及的(标准库)特化std::complex.我们不能一致地模仿语义.

我认为很明显将三个不同的成员视为数组元素是行不通的,因为指向它们的指针算法受到极大的限制(例如,添加1会产生指针过去的结尾).

所以我们假设vec3包含一个由三个ints组成的数组.即使这样,reinterpret_cast<int*>(&v)你隐含需要的底层(在哪里v是a vec3)也不会给你一个指向第一个元素的指针.请参阅指针可互换性的详尽要求:

两个对象a,如果符合以下情况,b指针可互换:

  • 它们是同一个对象,或者

  • 一个是标准布局联合对象,另一个是该对象的非静态数据成员([class.union]),或者

  • 一个是标准布局类对象,另一个是该对象的第一个非静态数据成员,或者,如果该对象没有非静态数据成员,则该对象的第一个基类子对象([class.mem]) ), 要么

  • 存在一个物体c,使得ac是指针相互转化,和cb是指针的互变的.

如果两个对象是指针可互换的,那么它们具有相同的地址,并且可以通过a获得指向另一个指针的指针reinterpret_­cast.[  注意:数组对象及其第一个元素不是指针可互换的,即使它们具有相同的地址.  -  结束说明  ]

这是非常明确的; 虽然我们可以得到一个指向数组的指针(作为第一个成员),虽然指针 - 可互换性是可传递的,但我们无法获得指向其第一个元素的指针.

最后,即使你设法获得指向成员数组的第一个元素的指针,如果你有一个vec3s 数组,你也不能 使用简单的指针增量遍历所有成员数组,因为我们得到了指针的结尾.中间的数组.swder也没有解决这个问题,因为与指针相关联的对象不共享任何存储(cf [ptr.launder]了解具体内容).

  • "洗涤"有什么帮助?另外,为什么数组不能与第一个元素相互转换?(这些可能过于宽泛而无法发表评论......) (2认同)
  • @bogdan在P0137r0之后,我没有看到`washder`的措辞.你是对的.实际上,多维数组的平面迭代是完全不可能的,这太可惜了! (2认同)

Lig*_*ica 5

只有在编译器的特殊支持下才能实现.

工会不会让你到那里因为常见的方法实际上有未定义的行为,虽然布局兼容的初始序列有例外,你可以通过unsigned char*一个特殊情况检查一个对象.不过就是这样.

有趣的是,除非我们假设"下面"具有广泛而无用的含义,否则该标准在技术上是矛盾的:

[C++14: 5.2.10/1]: [..]下面列出了可以使用reinterpret_cast显式执行的转换.使用reinterpret_cast不能显式执行其他转换.

complex<T>然后没有提到案例.最后,您提到的规则将在很长一段时间后推出[C++14: 26.4/4].

  • 什么转换?将一个对象左值转换为另一个对象类型的左值引用?那不像第11段吗? (3认同)