对于包含包装类型和类型本身的联合,是否有任何保证?

Zet*_*eta 11 c++ struct types unions language-lawyer

我可以把T和一个包裹Tunion并检查他们,因为我喜欢?

union Example {
    T value;
    struct Wrapped { 
       T wrapped;
    } wrapper;
};
Run Code Online (Sandbox Code Playgroud)
// for simplicity T = int

Example ex;
ex.value = 12;
cout << ex.wrapper.wrapped; // ?
Run Code Online (Sandbox Code Playgroud)

C++ 11标准只保证保存对常见初始序列的检查,但value不是struct.我答案是否定的,因为包装类型甚至不能保证与其解包对应的内存兼容,并且访问非活动成员只能在常见的初始序列上明确定义.

Bar*_*rry 4

我相信这是未定义的行为。

[class.mem]给我们:

两个标准布局结构类型的公共初始序列是声明顺序中非静态数据成员和位字段的最长序列,从每个结构中的第一个此类实体开始,以便相应的实体具有布局兼容的类型并且要么两个实体都不是位字段,要么两者都是具有相同宽度的位字段。[...]

在具有 struct 类型的活动成员的标准布局联合中T1,允许读取mstruct 类型的另一个联合成员的非静态数据成员,前提是 m 是和T2的公共初始序列的一部分;该行为就像 的相应成员被提名一样。T1T2T1

如果T不是标准布局结构类型,则这显然是未定义的行为。(请注意,这int不是标准布局结构类型,因为它根本不是类类型)。

但即使对于标准布局结构类型,“公共初始序列”的构成也严格基于非静态数据成员。也就是说,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; // (*)
Run Code Online (Sandbox Code Playgroud)

您正在访问联盟的非活跃成员。那是未定义的。