您可以通过 T 的结构为 T 的数组添加别名吗,类似于 std::complex[N] 如何为 T[N * 2] 别名? [复制]

2023-12-27

从 C++11 开始std::complex<T>[n]保证可别名为T[n*2],具有明确定义的值。这正是人们对任何主流架构所期望的。

对于我自己的类型,使用标准 C++ 可以实现这种保证吗?struct vec3 { float x, y, z; }或者只有在编译器的特殊支持下才可能实现?


TL;DR:编译器必须检查reinterpret_casts 并找出(标准库)的专业化std::complex都参与其中。我们无法一致地模仿语义。

我认为很明显,将三个不同的成员视为数组元素是行不通的,因为指向它们的指针的指针算术受到极大的限制(例如,加 1 会产生一个指针越过末尾 http://eel.is/c++draft/basic.compound#3).

所以我们假设vec3包含三个数组int代替。 即便如此,底层reinterpret_cast<int*>(&v)你隐含地需要(其中v is a vec3) 不会留下指向第一个元素的指针。请参阅详细要求指针互换性 http://eel.is/c++draft/basic.compound#4:

两个物体a and b are 指针可互换 if:

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

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

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

  • 存在一个物体c这样a and c是指针可相互转换的,并且c and b是 指针可相互转换。

如果两个对象是指针可相互转换的,那么它们具有相同的 地址,并且可以从指针获得指向一的指针 通过a到另一个reinterpret_­cast. [ Note: 数组对象 和它的第一个元素不是指针可相互转换的,即使 他们有相同的地址。  — end note ]

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

最后,即使您设法获得了指向成员数组第一个元素的指针,如果您有一个数组vec3s,你不能traverse所有成员数组都使用简单的指针增量,因为我们得到的指针超出了数组之间的末尾。 launder 也没有解决这个问题,因为与指针关联的对象不共享任何存储(参见[ptr.launder] http://eel.is/c++draft/ptr.launder#1了解具体情况)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

您可以通过 T 的结构为 T 的数组添加别名吗,类似于 std::complex[N] 如何为 T[N * 2] 别名? [复制] 的相关文章

随机推荐