我可以将一个 T
和一个包装的 T
放在一个 union
中并根据需要检查它们吗?
union Example {
T value;
struct Wrapped {
T wrapped;
} wrapper;
};
// for simplicity T = int
Example ex;
ex.value = 12;
cout << ex.wrapper.wrapped; // ?
C++11 标准只保证公共(public)初始序列的保存检查,但 value
不是 struct
。我猜想答案是否,因为wrapped types aren't even guaranteed to be memory compatible to their unwrapped counterpart和 accessing inactive members is only well-defined on common initial sequences .
最佳答案
我认为这是未定义的行为。
[class.mem]给我们:
The common initial sequence of two standard-layout struct types is the longest sequence of non-static data members and bit-fields in declaration order, starting with the first such entity in each of the structs, such that corresponding entities have layout-compatible types and either neither entity is a bit-field or both are bit-fields with the same width. [...]
In a standard-layout union with an active member of struct type
T1
, it is permitted to read a non-static data memberm
of another union member of struct typeT2
provided m is part of the common initial sequence ofT1
andT2
; the behavior is as if the corresponding member ofT1
were nominated.
如果 T
不是标准布局结构类型,这显然是未定义的行为。 (请注意,int
不是标准布局结构类型,因为它根本不是类类型)。
但即使对于标准布局结构类型,构成“公共(public)初始序列”的内容也严格基于非静态数据成员。即 T
和 struct { T val;
没有共同的初始序列 - 根本没有共同的数据成员!
因此,这里:
template <typename T>
union Example {
T value;
struct Wrapped {
T wrapped;
} wrapper;
};
Example<int> ex;
ex.value = 12;
cout << ex.wrapper.wrapped; // (*)
您正在访问一个不活跃的联盟成员。这是未定义的。
关于c++ - 包含包装类型和类型本身的 union 是否有任何保证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48058545/