まず、2行のコードで、スコープ付き列挙型とスコープなし列挙型を理解します。
enum Color{black,white,red}; //不限作用域的枚举类型
enum class Color{black,white,red}; //限定作用域的枚举类型,多了一个class关键字
スコープ付き列挙型を好む理由は3つあります。
1.名前空間の汚染を減らします。列挙値名が変数名と競合しないようにします。
//不限作用域的枚举类型
enum Color{black,white,red};
auto white = false; //变量white与枚举值white名称冲突
//限定作用域的枚举类型
enum class Color{black,white,red};
auto white = false; //不冲突
2.列挙型はより強力な型であり、static_castキーワードを使用して型変換を強制しない限り、他の型への暗黙的な変換は禁止されています。
//不限作用域的枚举类型
enum Color{black,white,red};
Color c = 1; //可以与整型直接隐式转换
//限定作用域的枚举类型
enum class Color{black,white,red};
Color c = 1; //编译报错,不能直接转换,需要借助static_cast关键字
3.前方宣言を直接行うことができます
enum Color; //不知道底层实现,编译报错,不能进行前置声明
enum class Color; //底层实现默认为int,可以进行前置声明
無制限の列挙型を前方宣言できない理由について、簡単に紹介します。列挙型の範囲の無制限のスコープを表現できるようにするために、コンパイラは通常、その範囲を表すのに十分な型を選択します。列挙型基本的な実装として、たとえば、列挙値が1〜10の場合、shortを使用できますが、この時点で0xFFFFFFFFの新しい値が追加されると、コンパイラはそれを表すためにlongを使用する必要があります。 。この時点で、列挙値が使用されるすべての場所が再コンパイルされることに注意してください。したがって、無制限スコープの列挙型の基になる実装を知る方法がないため、それにスペースを割り当てる方法がありません。前方宣言はありません。スコープ付き列挙型を事前に宣言できる理由は、デフォルトで基になる実装としてintを使用するためです。
宣言時にその基礎となる実装を指定すると、スコープが無制限の列挙型を事前に宣言することもできます。次に例を示します。
enum Color::int; //指定了底层类型,可以前置声明
enum class Color::int;//同理,限定作用域的枚举类型也可以指定底层类型
速記
- C ++ 98スタイルの列挙型(現在はスコープなしの列挙型と呼ばれています)、C ++ 11の列挙型はスコープ付きの列挙型と呼ばれています
- スコープ指定された列挙型は、列挙型内でのみ表示され、static_castを介して他の型にのみキャストできます。
- スコープ付き列挙型とスコープなし列挙型の両方が、基になる実装型の指定をサポートします。スコープ付き列挙型のデフォルトの基になる型はintであり、スコープ付き列挙型にはdefault.valueがありません。
- スコープ付き列挙型は前方宣言できますが、スコープなし列挙型は、基になる実装タイプを手動で指定した後でのみ前方宣言できます。