ProgrammingシニアC++開発者

C++における'enum class'(スコープ付き列挙型)メカニズムについて説明してください。従来の列挙型とどのように異なり、なぜ導入されたのか。また、古いenumからenum classへの移行時に典型的なエラーは何ですか?

Hintsage AIアシスタントで面接を突破

答え

C++11で'enum class'メカニズム—キーワードenum classが導入されました。

従来のenumとの主な違い:

  • enum classの内容は独自のスコープを持っており、グローバル名前空間の汚染がありません。
  • 列挙子がintに暗黙的に変換されず(明示的なキャストが必要です)。
  • enum classのデフォルト型はintですが、別の型を指定することも可能です(例: 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を宣言し、列挙子を修飾子なしで使用した結果、異なるコードがコンパイルされたり、重複する名前によるリンカエラーが発生しました。