不止一个枚举声明

时间:2014-05-17 08:01:58

标签: c++ enums language-lawyer

来自sec的引用。 N3797工作草案的3.3.1 / 4:

  

在单个声明性区域中给出一组声明,每个声明   它指定相同的非限定名称,

     

- 正好一个声明应声明一个类名或枚举   名称不是typedef名称,其他声明都是   引用相同的变量或枚举,或全部引用函数   和功能模板;

我们可以在单个声明性区域中多次声明enum类型名称:

enum A; // declared first time, the other declaration with the same
        // unqualified name shall all refer to the same variable or enumeration.
enum A; // This and the other declarations shall all refer to the that enumeration
extern int A; // Fail, now enum A is hidden and we can access it
              // via elaborated-type-specifier only

我很困惑。你能解释一下这种行为吗?我想找到对当前工作草案的相应引用。

2 个答案:

答案 0 :(得分:2)

完整报价n3797 3.3.1 / 4是:

  

在单个声明性区域中给出一组声明,每个声明都指定相同的非限定名称,

     

- 它们都应引用同一个实体,或全部引用功能和功能模板;或

     

- 正好一个声明应声明一个不是typedef名称的类名或枚举名   其他声明都应引用相同的变量或枚举,或全部引用功能和功能模板;在这种情况下,类名或枚举名称是隐藏的。

你写的代码是错误的。有关所需语法,请参见S7.2,其中可能是以下任何一种语法:

enum A : int; // declaration (and it is an enumeration name)
enum A : int; // refers to the same entity

enum struct A; // declaration (and it is an enumeration name)
enum struct A; // refers to the same entity

enum A {}; // declaration (and it is an enumeration name)
enum A {}; // refers to the same entity

然后在翻译单元中可能会出现以下情况。

extern int A; // declaration hides enumeration name

void f() {
  A j = A.a; // illegal. A is hidden
  int k = A; // legal
}

见n3797 3.3.10 / 2:

  

类名(9.1)或枚举名(7.2)可以通过变量名称,数据成员隐藏,   在同一范围内声明的函数或枚举器。如果类或枚举名称和变量,数据成员,函数或枚举器在同一作用域(按任何顺序)中声明具有相同名称,则类或枚举名称将隐藏在变量,数据成员,函数或枚举器名称可见。

所以最后的A隐藏了之前的那些。这就是你问的问题吗?


回答问题:该计划是否良好?显然这些只是片段,并没有提供完整的程序,但如果这些是A的唯一引用,它们是否合法?我的回答是肯定的。 S7.2 / 6说:

  

其基础类型是固定的枚举是从声明(3.3.2)到紧跟其枚举(如果有)之后的不完整类型,此时它变为完整类型。其基础类型未修复的枚举是从其声明点到其枚举说明符的关闭之后的不完整类型,此时它变为完整类型。

因此,在给出的每个示例中,A是完整类型,如图所示。 7.2 / 3说:

  

opaque-enum-declaration是对当前作用域中枚举的重新声明或新枚举的声明。 [注意:opaque-enum-declaration声明的枚举具有固定的底层类型,并且是完整类型。可以在稍后的重新声明中使用enumspecifier提供枚举器列表。 -end note]范围内的枚举不得在以后重新声明为无范围或具有不同的基础类型。未覆盖的枚举不得在以后重新声明为范围,每个重新声明应包括一个枚举基础,指定与原始声明中相同的基础类型。

因此,只要属性和基数相同,似乎可以重复这些声明,但是一旦提供了枚举数列表,这些声明似乎就不会重复。

对于前两个,似乎程序结构良好,但也许不是最后一个。

答案 1 :(得分:0)

我认为你做错了。枚举器(枚举)是一种类型,如果你写的是      enum A;
 您为此类型命名,但您仍然没有任何变量。声明有两种可能的方式。 你可以写:
enum A { a, b, c };
,现在你有3个变量{a,b,c},它们的类型是枚举,类型名称是A.第二种方式是:
                enum NAME; NAME var1; NAME var2;
您还可以使用未命名的变量:
enum { a, b, c };
当您需要常量名称但不打算使用该类型来声明变量,函数参数等时,可以使用此方法。