c – 如何将我的对象重新解释为可转换为数组,例如std :: complex?

我刚刚学习了这个因为 this question,std :: complex的标准状态(26.4 [complex.numbers]):

4 If z is an lvalue expression of type cv std::complex<T> then:
— the expression reinterpret_cast<cv T(&)[2]>(z) shall be well-formed,
reinterpret_cast<cv T(&)[2]>(z)[0] shall designate the real part of z,and
reinterpret_cast<cv T(&)[2]>(z)[1] shall designate the imaginary part of z.
Moreover,if a is an expression of type cv std::complex<T>* and the expression a[i] is well-defined for an integer expression i,then:
reinterpret_cast<cv T*>(a)[2*i] shall designate the real part of a[i],and
reinterpret_cast<cv T*>(a)[2*i + 1] shall designate the imaginary part of a[i].

这是我真正想要以符合标准的方式利用的东西.有些时候我有POD,比如数学向量,它们由单一数据类型组成.这是两个示例类:

template <typename T,unsigned N>
struct Vector
{
    T v[N];
};

template <typename T>
struct Quaternion
{
    T r,i,j,k;
};

根据我的理解,允许实现在最后一个成员之后以及成员之间添加填充.这意味着sizeof(Quaterntion< float>)可能不等于sizeof(float [4]),而sizeof(Vector< double,8>)可能不等于sizeof(double [8]).这意味着我通常必须在我的代码添加一些static_asserts以确保我可以投射我的Vector< float,N> / Quaterntion< float>例如,浮点*,不用担心填充(例如,传递给C库或OpenGL缓冲区).

是否有标准提供的方法可以让我对我的小POD(如Vector和Quaternion)提供相同的保证,就像std :: complex一样?我知道特定于实现的事情,比如__attribute __((packed)).我正在寻找一种非实现特定的,符合标准的方法.由于标准需要支持这种类型的东西用于提供std :: complex的实现,我想知道是否还有一些标准方法将此保证应用于我自己的类.

解决方法

我想你在问不可能.

请记住,标准库实现者通常依赖于非标准扩展或实现定义的行为.实际上,在VC的复杂标题中,我们发现:

#pragma pack(push,_CRT_PACKING)

// implementation

#pragma pack(pop)

您可以为Quaternion做的是将所有成员放在一个数组中,因为struct address可以reinterpret_cast到指向第一个成员的指针.但我想这种方法会破坏结构的目的(直接成员访问名称).

这不是你要求的,而是提供一个

operator const T*() const // can be written in a portable manner

对于你的结构,将允许你写

Quaternion<double> q = {};
const double * p = q;

以额外的运行时/内存开销为代价,具体取决于您实现转换运算符的方式.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...