C++11で'enum class'メカニズム—キーワードenum classが導入されました。
従来のenumとの主な違い:
enum class MyE : uint8_t { ... };)。なぜ必要なのか: 型の安全性を高め、名前の衝突を防ぎ、誤った比較を防ぎ、ストレージの明示的な管理を実現するため。
例:
enum Color { Red, Green }; Color c = Red; // 従来のenum、Redはグローバルに見える enum class State { Off, On }; State s = State::On; // State::Onを指定する必要がある
書いてはいけない:
enum class State { Off, On }; int x = State::On; // エラー!キャストのみ int y = static_cast<int>(State::Off); // OK
なぜ異なるenum classの値間で論理的比較を行うことができないのか、たとえ名前と基になる型が一致していても?
答え:
型の安全性:各enum classは独自の型であり、基になる型は同じで、列挙子の名前が一致していても、コンパイラーはそれを異なる型として扱い、暗黙の比較を許可しません。
ストーリー
機械制御プロジェクトでenumからenum classに移行した際、値をログに出力する際に明示的な変換を追加するのを忘れました。ログには「異物」の値が表示され始め(State::Onを数値として認識せず)、デバッグが難しくなりました。
ストーリー
RESTサービスで通常のenumをenum classに移行した後、異なるenum classからのさまざまな列挙型の値を比較するコードがありました。コンパイラーはこれを許可しなかったため、自動テストがビルドできない状態になりました。
ストーリー
監査システムでは、開発者が古い構文と新しい構文を混同し、しばしば意図せずenum classを宣言し、列挙子を修飾子なしで使用した結果、異なるコードがコンパイルされたり、重複する名前によるリンカエラーが発生しました。