匿名联合和结构 [英] Anonymous union and struct
问题描述
您将如何在标准C ++ 11/14中执行此操作?因为如果我没记错的话,这不是具有匿名结构的标准兼容代码。
How would you go about doing this in standard C++11/14 ? Because if I'm not mistaken this isn't standard compliant code with the anonymous structs.
我希望以与您相同的方式访问成员。 / p>
I wish to access the members the same way as you would with this.
template <typename some_type>
struct vec
{
union {
struct { some_type x, y, z; };
struct { some_type r, g, b; };
some_type elements[3];
};
};
推荐答案
是的,C ++ 11和C ++都不14允许匿名结构。 此答案包含这种情况的一些原因。您需要命名结构,它们也不能在匿名联合中定义。
Yes, neither C++11 nor C++14 allow anonymous structs. This answer contains some reasoning why this is the case. You need to name the structs, and they also cannot be defined within the anonymous union.
§9.5/ 5 [class.union]
...
成员的成员规范匿名联合只能定义非静态数据成员。 [注意:嵌套类型,匿名联合和函数不能在匿名联合中声明。 -尾注]
...
The member-specification of an anonymous union shall only define non-static data members. [ Note: Nested types, anonymous unions, and functions cannot be declared within an anonymous union. —end note ]
因此将结构定义移到并集之外。
So move the struct definitions outside of the union.
template <typename some_type>
struct vec
{
struct xyz { some_type x, y, z; };
struct rgb { some_type r, g, b; };
union {
xyz a;
rgb b;
some_type elements[3];
};
};
现在,我们要求 some_type
为 standard-layout ,因为这使匿名联合的所有成员 layout兼容。 这是标准布局类型的要求。在标准的第§9/ 7节中对此进行了描述。
Now, we require some_type
to be standard-layout because that makes all the members of the anonymous union layout compatible. Here are the requirements for a standard layout type. These are described in section §9/7 of the standard.
然后,来自§9.2[class.mem]
16 如果两个标准布局结构(条款9)类型具有相同数量的非静态数据成员,并且对应的非静态数据成员(按声明顺序)具有布局兼容类型(3.9),则它们与布局兼容。 >
18 如果标准布局联合包含两个或多个共享公共初始序列的标准布局结构,并且如果标准布局联合对象当前包含这些标准布局结构之一,则可以检查任何标准布局结构的公共初始部分其中。如果相应的成员具有与布局兼容的类型,并且对于一个或多个初始成员的序列,两个成员都不是位字段,或者两者都不是具有相同宽度的位字段,则两个标准布局结构共享一个公共的初始序列。 >
16 Two standard-layout struct (Clause 9) types are layout-compatible if they have the same number of non-static data members and corresponding non-static data members (in declaration order) have layout-compatible types (3.9).
18 If a standard-layout union contains two or more standard-layout structs that share a common initial sequence, and if the standard-layout union object currently contains one of these standard-layout structs, it is permitted to inspect the common initial part of any of them. Two standard-layout structs share a common initial sequence if corresponding members have layout-compatible types and either neither member is a bit-field or both are bit-fields with the same width for a sequence of one or more initial members.
对于数组成员,来自§3.9/ 9 [basic.types]
...
标量类型,标准布局类类型(第9条),数组这样的类型
和这些类型的cv限定版本(3.9.3)统称为 standard-layout类型。
...
Scalar types, standard-layout class types (Clause 9), arrays of such types and cv-qualified versions of these types (3.9.3) are collectively called standard-layout types.
要确保 some_type
是标准布局,请在 vec
To ensure that some_type
is standard layout, add the following within the definition of vec
static_assert(std::is_standard_layout<some_type>::value, "not standard layout");
std :: is_standard_layout
在 type_traits
标头中定义。现在,联合的所有3个成员都是标准布局,两个结构和数组都与布局兼容,因此这3个联合成员共享一个公共的初始序列,这使您可以编写然后检查(读取)属于该公共的任何成员初始序列(整个情况)。
std::is_standard_layout
is defined in the type_traits
header. Now all 3 members of your union are standard layout, the two structs and the array are layout compatible, and so the 3 union members share a common initial sequence, which allows you to write and then inspect (read) any members belonging to the common initial sequence (the entire thing in your case).
这篇关于匿名联合和结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!