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



我真的很想以符合标准的方式利用这一点。有时候,我有像数学 vector 这样的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_assert,以确保可以将自己的Vector<float, N>/Quaterntion<float>强制转换为float*,而不必担心填充(例如,传递给C库或OpenGL缓冲区)。

标准提供了一些方法,可以让我像Vector一样为我的小POD提供相同的保证吗?我知道特定于实现的东西,例如Quaternion。我正在寻找一种非实现特定的,符合标准的方法。由于该标准要求提供std::complex的实现支持这种类型的东西,所以我想知道是否存在一些将这种保证应用于我自己的类的标准方法。

最佳答案

我想你在问不可能的事。

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

#pragma pack(push, _CRT_PACKING)

// implementation

#pragma pack(pop)

对于四元数,您可以做的是将所有成员放置在数组中,因为可以将struct地址重新解释为指向第一个成员的指针。但是我猜想这种破坏了结构的目的(按名称直接访问成员)。

这并不完全是您要的,而是提供了
operator const T*() const // can be written in a portable manner

为您的结构,将允许您编写
Quaternion<double> q = {};
const double * p = q;

取决于额外的运行时/内存开销,具体取决于实现转换运算符的方式。

关于c++ - 如何使我的对象重新解释可广播到数组,例如std::complex?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22925905/

10-12 20:41