簡體   English   中英

“靜態枚舉”在C ++中意味着什么?

[英]What does “static enum” mean in C++?

我最近遇到過這個:

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

它在Microsoft VS2005下編譯和工作。 但是,我不確定'靜態'修飾符應該做什么。 它與以下有什么不同嗎?

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

刪除省略號的確切代碼不是有效的C ++。 您不能在enum聲明中使用static存儲類說明符; 它沒有任何意義(只有對象,函數和匿名聯合可以聲明為static )。

但是,您可以在一個聲明中聲明enum和變量:

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

這里的static適用於x ,它實際上與你說的一樣:

enum Response { 
    NO_ERROR = 0,
    MISSING_DESCRIPTOR
};

static Response x;

令人驚訝的是,你也可以在其中放置其他的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 一切都很奇怪。

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

您無法在C ++中定義static枚舉。 static只能是枚舉的變量 ,而不是類型本身!

使用GCC版本4.3.4編譯代碼時,會出現此錯誤:

prog.cpp:7:錯誤:只能為對象和函數指定存儲類

在ideone上在線查看: http//www.ideone.com/cI1bt

我認為這一切都說。

-

但是,如果要在其自己的轉換單元中限制類型 enum Response ,則可以使用未命名的命名空間。 看看這個主題:

未命名的命名空間優於靜態?

標准

C ++ 11 N3337標准草案附件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符號。

當編譯器看到枚舉值時,它只是將其字面插入到編譯的代碼中。 這當然有效,因為它們是編譯時常量。

因此,它們必須包含在頭文件中。

也可以看看:

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

我不確定為什么靜態使用或為什么它甚至編譯。 應該只是枚舉響應。 枚舉器不是靜態數據。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM