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)
你的方式是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)