“静态枚举”在C ++中意味着什么?

时间:2011-02-11 16:22:17

标签: c++ visual-studio enums static

我最近遇到过这个:

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

它在Microsoft VS2005下编译和工作。但是,我不确定'静态'修饰符应该做什么。它与以下有何不同?

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

6 个答案:

答案 0 :(得分:57)

只删除省略号的确切代码不是有效的C ++。您不能在static声明中使用enum存储类说明符;它没有任何意义(只能声明对象,函数和匿名联合static)。

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

static enum Response {
    NO_ERROR = 0,
    MISSING_DESCRIPTOR
} x; 

此处static适用于x,它实际上与您说的相同:

enum Response { 
    NO_ERROR = 0,
    MISSING_DESCRIPTOR
};

static Response x;

答案 1 :(得分:14)

令人惊讶的是,您也可以在其中放置其他 decl-specifiers 这在VS2008中编译得很好:

auto const enum TestEnum {
    Why,
    Does
};

register volatile enum TestEnum2 {
    This,
    Work
};

但它完全没有意义:)

我怀疑这里的问题是在解析中,因为这样的代码:

enum TestEnum3 { Hello, World };  // Define enum
enum TestEnum3 x = World;         // Use enum

也可以写成:

enum TestEnum3 { Hello, World } x = World; // Define and use enum.

有趣的是,我注意到你是否在VS2008中这样做了:

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-specifier 。一切都很奇怪。

答案 2 :(得分:7)

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

您无法在C ++中定义static枚举。 static只能是枚举的变量,而不是类型本身!

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

  

prog.cpp:7:错误:存储类可以   只能为对象指定   功能

通过ideone:http://www.ideone.com/cI1bt

在线查看自己

我认为这就是全部。

-

但是,如果要在其自己的翻译单元中限制类型 enum Response,则可以使用未命名的命名空间。看看这个主题:

Superiority of unnamed namespace over static?

答案 3 :(得分:2)

标准

C++11 N3337 standard draft附件C 7.1.1说它在C中被允许但没有效果,并且在C ++中变得非法:

  

更改:在C ++中,静态或外部说明符只能应用于对象或函数的名称。   在C ++中使用带有类型声明的这些说明符是非法的。在C中,使用时会忽略这些说明符   在类型声明。例如:

static struct S {    // valid C, invalid in C++
  int i;
};
  

基本原理:与类型关联时,存储类说明符没有任何意义。在C ++中,类   可以使用静态存储类说明符声明成员。允许类型的存储类说明符   声明可能会使代码对用户造成混淆。

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

实施原理

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

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

使用:

g++ -c main.c
nm main.o

您会看到没有S符号,但有一个i符号。

当编译器看到枚举值时,它只是将其字面插入到编译的代码中。这当然有效,因为它们是编译时常量。

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

另见:

答案 4 :(得分:1)

在C#中:

';'对于枚举块后的向后兼容性是可选的。对于命名类型,允许使用该语言的这种语义。静态,公共等都有特殊的考虑。命名空间不能包含字段或方法等成员。

需要标记:

ArgTypes var = ArgTypes.CUT;

在C / C ++中:

需要';'在枚举块的末尾。 对于全局命名空间变量,枚举等,默认情况下为 static

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 ** */

答案 5 :(得分:0)

我不确定为什么使用静态或为什么它甚至编译。应该只是枚举响应。 枚举器不是静态数据。