包含包装类型和类型本身的联合是否有保证? [英] Are there any guarantees for unions that contain a wrapped type and the type itself?
问题描述
我可以将T
和包裹的T
放入union
中,并根据需要检查它们吗?
Can I put a T
and a wrapped T
in an union
and inspect them as I like?
union Example {
T value;
struct Wrapped {
T wrapped;
} wrapper;
};
// for simplicity T = int
Example ex;
ex.value = 12;
cout << ex.wrapper.wrapped; // ?
C ++ 11标准仅保证对公共初始序列进行保存检查,但value
不是struct
.我猜答案是否,因为访问非活动成员仅在常见的初始序列上进行了明确定义.
The C++11 standards only guarantee save inspection of the common initial sequence, but value
isn't a struct
. I guess the answer is no, since wrapped types aren't even guaranteed to be memory compatible to their unwrapped counterpart and accessing inactive members is only well-defined on common initial sequences.
推荐答案
我认为这是未定义的行为.
I believe this is undefined behavior.
[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. [...]
在具有结构类型为T1
的活动成员的标准布局联合中,允许读取结构类型为T2
的另一个联合成员的非静态数据成员m
,前提是m是该类型的一部分. T1
和T2
的共同初始序列;行为就像T1
的相应成员被提名一样.
In a standard-layout union with an active member of struct type T1
, it is permitted to read a non-static data member m
of another union member of struct type T2
provided m is part of the common initial sequence of T1
and T2
; the behavior is as if the corresponding member of T1
were nominated.
如果T
不是标准的布局结构类型,则这显然是未定义的行为. (请注意,int
不是标准布局结构类型,因为它根本不是类类型.)
If T
isn't a standard layout struct type, this is clearly undefined behavior. (Note that int
is not a standard layout struct type, as it's not a class type at all).
但是,即使对于标准布局结构类型,构成公共初始序列"的条件也严格基于非静态数据成员.也就是说,T
和struct { T val; }
没有共同的初始序列-根本没有共同的数据成员!
But even for standard layout struct types, what constitutes a "common initial sequence" is based strictly on non-static data members. That is, T
and struct { T val; }
do not have a common initial sequence - there are no data members in common at all!
因此,在这里:
template <typename T>
union Example {
T value;
struct Wrapped {
T wrapped;
} wrapper;
};
Example<int> ex;
ex.value = 12;
cout << ex.wrapper.wrapped; // (*)
您正在访问工会的不活跃成员.那是不确定的.
you're accessing an inactive member of the union. That's undefined.
这篇关于包含包装类型和类型本身的联合是否有保证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!