【C++】enum class – スコープを持つ列挙型
はじめに
C++11より、従来の列挙型を拡張したenum classが追加されました。これにより、より安全に列挙型を使うことができるようになります。このエントリでは、enum classについてまとめてみました。
特徴
- スコープを持つため、名前の衝突を避けることができる
- 整数型への暗黙の型変換を行わない
- 整数型の基底型(
char
,unsigned int
など)を指定することができる enum class
で定義された値以外は使用できない
使い方
定義方法
enum class 型名 : 基底型 {
列挙子1 = 整数値, 列挙子2, ...
};
従来の列挙型と同じような方法で定義可能です。enum class
はenum struct
でも構いません。どちらの方法でも機能的な違いはありません。
基底型を指定しなかった場合はint
型となります。また、整数値を指定しなかった場合は、前の値に+1した値が割り当てられる点は、従来の列挙型と同じです。基底型を指定した場合、その基底型の範囲を超えるような値を使うことはできません。
使用例
// 定義
enum class Number : unsigned int {
Zero = 0, One, Two, Three
};
// 変数の宣言
Number v;
// 変数への代入
v = Number::One;
// v = 4 // <- 定義した値以外は代入できない
// 整数型変数への代入
unsigned int int_v = static_cast<unsigned int>(v);
// unsigned int int_v = v // <- 基底型が同じでも直接代入はできない
従来のenum
と違い、定義した値はスコープを持つため、アクセスするには必ず型名::列挙子
の形にしなければなりません。ちょっと面倒ですが、これにより名前の衝突を避けることができます。名前空間ではないので、using
を使って省略することはできません。
また、定義した値以外は使うことができません。宣言した変数にただの整数値を代入することはできません。
注意が必要なのは、整数型変数への代入や、整数値として扱いたい場合です。この場合は、型をstatic_cast<>()
を使ってキャストする必要があります。基底型が同じであってもキャストが必要です。
// 変数の比較
if(v == Number::Zero){
...
}
else if(v >= Number::One){
...
}
switch(v){
case Number::Zero:
...
default:
...
}
比較は、従来と同じように行うことができます。等号だけでなく、不等号も使えます。定義値以外の整数値と比較する場合は、キャストが必要です。
まとめ
スコープを持つ列挙型enum class
についてまとめてみました。
- スコープを持つため、名前の衝突を避けることができる
- 整数型への暗黙の型変換を行わない。整数型として扱う場合は、
static_cast<>()
による型変換が必要 - 整数型の基底型を指定することができる。このとき、基底型を超える範囲の値は定義できない
enum class
で定義された値以外は使用できない- 定義された値との比較は、従来と同様に書くことができる
ディスカッション
コメント一覧
まだ、コメントがありません