【发布时间】:2017-06-26 22:46:44
【问题描述】:
假设我有一个包含多个成员的结构,每个成员都属于同一类型。我想通过名称和数组索引安全地访问成员,所以我引入了一个union,它包含实际的struct和一个数组,它对应于struct的成员数量和类型。请参阅以下代码,该代码说明了我想如何使用 union 以两种不同的方式“查看”struct:
#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;
}
}
假设数组的内存布局与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");
【问题讨论】:
-
访问
union的活动元素以外的任何内容都是未定义的行为。 -
您可以将
operator[]添加到您的班级。
标签: c++ arrays struct language-lawyer unions