枚舉類型
從C++11開始,存在了兩種枚舉類型Unscoped enumeration
和Scoped enumeration
Unscoped enumeration
是C++98風格的枚舉,也是平時使用的最多的,enum Direction { East, South, West, North }
Scoped enumeration
是C++11引入的新的枚舉類型,也是更推薦使用的枚舉。完整的定義如下enum struct|class name : type { enumerator = constexpr , enumerator = constexpr , ... }
定義的方式和Unscoped enumeration
大體一致,只有兩個部分有些差異:
struct | class
: 只要使用了struct
或者class
關鍵字,就表示定義了Scoped enumeration
,而這兩個關鍵字本身是等價的,隨便使用哪個都沒有區別,根據慣例的話更偏向使用class
type
:其實C++11
以后,兩種類型的枚舉都可以指定type
。這個類型是可以缺省的,這樣默認使用的就是int
類型。如果不符合自己的使用場景,也可以自己指定類型,但該類型屬于integral type
,如char
、int
、uint8_t
等。
Scoped enums的優勢
- 減少命名空間的污染
在包含Unscoped enum
的作用域內,定義的任何變量不可以和枚舉符重名
enum Color {
red, green, blue
};
enum class Animal {
cat, dog, fish
};
auto red = "red"; // error! redefinition of 'red' as different kind of symbo
auto cat = "cat"; // OK
- 強類型
Unscoped enum
可以隱式地轉化為整型,意味著枚舉符可以當作整型,甚至float
來使用,在某些情況下會引起難以察覺的bug,這也是C++11
的期望解決的
enum Color {
red, green, blue
};
enum class Animal {
cat, dog, fish
};
int a = red; // OK
int b = Animal::cat; // Error, cannot initialize a variable of type 'int' with an rvalue of type 'Animal'
Animal c = Animal::cat; // OK
// 當然,如果你非要轉化成int也是可以的,雖然不推薦這樣做
// 如果遇到這樣的情況,更推薦使用Unscoped enum
int d = static_cast<int>(Animal::cat);
參考資料
- Effective Modern C++
- cppreference.com