4 If
z
is an lvalue expression of type cvstd::complex<T>
then:
— the expressionreinterpret_cast<cv T(&)[2]>(z)
shall be well-formed,
—reinterpret_cast<cv T(&)[2]>(z)[0]
shall designate the real part ofz
,and
—reinterpret_cast<cv T(&)[2]>(z)[1]
shall designate the imaginary part ofz
.
Moreover,ifa
is an expression of type cvstd::complex<T>*
and the expressiona[i]
is well-defined for an integer expressioni
,then:
—reinterpret_cast<cv T*>(a)[2*i]
shall designate the real part ofa[i]
,and
—reinterpret_cast<cv T*>(a)[2*i + 1]
shall designate the imaginary part ofa[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;
以额外的运行时/内存开销为代价,具体取决于您实现转换运算符的方式.