以类似方式访问数组中的struct成员:在数组中填充不同于数组的结构?

Ste*_*ner 3 c++ arrays struct unions language-lawyer

假设我有一个包含几个成员的结构,每个成员属于同一类型.我想通过名称和数组索引安全地访问成员,所以我介绍了一个union包含实际struct和数组的数组,它对应于struct数字和类型方面的成员.请参阅以下代码,其中说明了如何使用以下struct两种方式"查看"以下两种方式union:

#include <iostream>

template<typename elemT>
struct productData {
    elemT color;
    elemT size;
    elemT application;
    elemT division;
};

template<typename elemT>
union productDataAsArray {
    struct productData<elemT> p;
    elemT arr[(sizeof(productData<elemT>) / sizeof(elemT))];
};

int main() {

    union productDataAsArray<int> myProduct;
    myProduct.p.color = 10;
    myProduct.p.size = 20;
    myProduct.p.application = 30;
    myProduct.p.division = 40;

    for (int i=0; i<4; i++) {
        std::cout << "elem #" << i << ":" << myProduct.arr[i] << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

是否安全/保证标准假设数组的内存布局对应于内存布局struct,这样两种不同的访问方法可以实现任何类型的预期结果elemT

以下static_asserts几种不同的类型表明它应该工作.但实际上有保证吗?

static_assert(sizeof(productData<int>)==sizeof(productDataAsArray<int>::arr), "padding/alignment inconsistency");
static_assert(sizeof(productData<char>)==sizeof(productDataAsArray<char>::arr), "padding/alignment inconsistency");
static_assert(sizeof(productData<double>)==sizeof(productDataAsArray<double>::arr), "padding/alignment inconsistency");
static_assert(sizeof(productData<char*>)==sizeof(productDataAsArray<char*>::arr), "padding/alignment inconsistency");

class alignas(16) testClass {
    int x;
    int y;
    virtual void test() {};
};

static_assert(sizeof(productData<testClass>)==sizeof(productDataAsArray<testClass>::arr), "padding/alignment inconsistency");
Run Code Online (Sandbox Code Playgroud)

Jar*_*d42 5

你的方式是UB,你也可以这样做:

template<typename elemT>
class productData {
    elemT data[4];
public:
    const elemT& operator[](int i) const { return data[i];}
    const elemT& color() const { return data[0]; }
    const elemT& size() const { return data[1]; }
    const elemT& application() const { return data[2]; }
    const elemT& division() const { return data[3]; }

    elemT& operator[](int i) { return data[i];}
    elemT& color() { return data[0]; }
    elemT& size() { return data[1]; }
    elemT& application() { return data[2]; }
    elemT& division() { return data[3]; }
};
Run Code Online (Sandbox Code Playgroud)