C++ 什么是;“静态枚举”;以C+表示的平均值+;?

C++ 什么是;“静态枚举”;以C+表示的平均值+;?,c++,visual-studio,enums,static,C++,Visual Studio,Enums,Static,我最近遇到了这样一个问题: static enum Response{ NO_ERROR=0, MISSING_DESCRIPTOR, ... }; 它在Microsoft VS2005下编译和工作。但是,我不确定“static”修饰符应该做什么。它与下面的有什么不同吗 enum Response { NO_ERROR=0, MISSING_DESCRIPTOR, ... }; P>精确的代码,省略了省略号,不是有效的C++。不能在枚举声明中

我最近遇到了这样一个问题:

static enum Response{
    NO_ERROR=0,
    MISSING_DESCRIPTOR,
    ...
};
它在Microsoft VS2005下编译和工作。但是,我不确定“static”修饰符应该做什么。它与下面的有什么不同吗

enum Response {
    NO_ERROR=0,
    MISSING_DESCRIPTOR,
    ...
};

<> P>精确的代码,省略了省略号,不是有效的C++。不能在
枚举
声明中使用
静态
存储类说明符;这没有任何意义(只能声明对象、函数和匿名联合
静态

但是,您可以在一个声明中声明
enum
和变量:

static enum Response {
    NO_ERROR = 0,
    MISSING_DESCRIPTOR
} x; 
这里的
static
适用于
x
,实际上与您所说的相同:

enum Response { 
    NO_ERROR = 0,
    MISSING_DESCRIPTOR
};

static Response x;

我不知道为什么要使用static,或者为什么要编译它。应该只是枚举响应。 枚举数不是静态数据

static enum Response { /*... */ };

不能定义C++中的代码>静态< /代码>枚举。code>static只能是枚举的变量,不能是类型本身

使用
GCC
版本
4.3.4
编译代码时,会出现以下错误:

程序cpp:7:错误:存储类无法 只能为对象和对象指定 功能

在ideone在线查看您自己:

我想这就说明了一切

--

但是,如果您想将类型
enum Response
限制在它自己的转换单元中,那么可以使用未命名的命名空间。请看一下这个主题:


令人惊讶的是,您还可以在其中添加其他decl说明符。
这在VS2008中编译得很好:

auto const enum TestEnum {
    Why,
    Does
};

register volatile enum TestEnum2 {
    This,
    Work
};
enum TestEnum3 { Hello, World };
const enum TestEnum3 e3 = World;
const enum TestEnum4 { F, M, L } e4 = F;

e3 = Hello; // error C2166: l-value specifies const object (Good!)
e4 = M;     // NO ERROR here though - why?
但这毫无意义:)

我怀疑这里的问题在于解析,因为代码如下:

enum TestEnum3 { Hello, World };  // Define enum
enum TestEnum3 x = World;         // Use enum
也可以写成:

enum TestEnum3 { Hello, World } x = World; // Define and use enum.
有趣的是,我注意到如果您在VS2008中这样做:

auto const enum TestEnum {
    Why,
    Does
};

register volatile enum TestEnum2 {
    This,
    Work
};
enum TestEnum3 { Hello, World };
const enum TestEnum3 e3 = World;
const enum TestEnum4 { F, M, L } e4 = F;

e3 = Hello; // error C2166: l-value specifies const object (Good!)
e4 = M;     // NO ERROR here though - why?
因此,它们并不等同于
TestEnum4
的情况,它似乎抛弃了
const
decl说明符。都很奇怪。

用C: “;”对于枚举块之后的向后兼容性,是可选的。它不允许在该语言中为命名类型使用此类语义。静态、公共等有特殊考虑。命名空间不能包含字段或方法等成员

需要标签:

ArgTypes var = ArgTypes.CUT;

C/C++中的 需要“;”在枚举块的末尾。 对于全局名称空间变量、枚举等,默认为静态

int type;

typedef enum {
  TOKENIZE,
  CUT
} ArgTypes;
type = TOKENIZE;  /* <ArgTypes>::TOKENIZE */
type = ArgTypes::CUT;

// Recommended Use
enum ArgTypes {
  TOKENIZE,
  CUT
};  /* Same as above */

enum Test {
  TOKENIZE,
  CUT
} ArgTypes;
type = ArgTypes::TOKENIZE;
type = CUT;   /* Assign type =>  <Test>.CUT */
type = Test::CUT;

enum {
  TOKENIZE,
  CUT
} ArgTypes;  /* Unamed.. requires tag */
type = TOKENIZE; /* <unamed>.TOKENIZE=0 => #define TOKENIZE 0*/
type = ArgTypes::TOKENIZE;  /* ** ERROR ** */
int型;
类型定义枚举{
标记化,
削减
}argtype;
类型=标记化;/*::标记化*/
类型=ArgTypes::CUT;
//推荐使用
枚举ArgTypes{
标记化,
削减
};  /* 同上*/
枚举测试{
标记化,
削减
}argtype;
type=ArgTypes::标记化;
类型=切割;/*分配类型=>.CUT*/
类型=测试::切割;
枚举{
标记化,
削减
}ArgTypes;/*未指定。。需要标签*/
类型=标记化;/*。标记化=0=>#定义标记化0*/
type=ArgTypes::标记化;/**错误***/

标准

附录C 7.1.1说,它在C中是允许的,但没有任何效果,在C++中是非法的:

更改:在C++中,静态或外部说明符只能应用于对象或函数的名称。 在C++中,将这些说明符与类型声明一起使用是非法的。在C语言中,这些说明符在使用时被忽略 关于类型声明。例如:

理由:存储类说明符与类型关联时没有任何意义。在C++中,类 可以使用静态存储类说明符声明成员。允许在类型上使用存储类说明符 声明可能会让用户对代码感到困惑

struct
一样,
enum
也是一种类型声明

实施理由

枚举定义没有存储,也不会在变量和函数等对象文件中生成符号。只需尝试编译和反编译:

struct S { int i; int j; };
int i;
与:

您将看到没有
S
符号,但是有一个
i
符号

当编译器看到一个枚举值时,它只是将其直接插入到已编译代码中。这当然只起作用,因为它们是编译时常量

因此,它们必须包含在头文件中

另见:

  • C中静态结构的相关问题:

它是在头文件中还是在cpp文件中?刚刚在Visual Studio 2008中试用过,而且在那里编译时也毫无怨言。在.cpp文件中澄清它,并且在}和之间没有变量名;它不是变量声明。详细说明如何在VS2005、VS2008和VS2010()中声明
enum
的msdn页面没有提到
static
。可能是它允许的一个bug。显然,在C++的这种特殊味道下,你可以做到。不过,您对未命名名称空间的评论非常有趣,谢谢@马辛:不,你不能那样做。VS2005错误地编译了这个。阅读詹姆斯的回答;他解释了何时可以编写
static
enum,更重要的是它的确切含义。它使变量是静态的,而不是类型本身。根据这一点,似乎他们在解析器中真的有一个bug。感谢这个例子,“自动const”。我猜,因为这在C中是有效的,MSVC只是忘记在C++编译器中实现这一点。