コンテンツにスキップ

最終更新:2026-10-12

C++ enum class 強い型付けされた列挙

Effective modern C++ の Item 10: Prefer scoped enums to unscoped enum では、スコープを持たない enum の代わりにスコープを持つ enum class を使うように説かれています。

例:

enum Shape {circle,retangle};
auto circle = 10;  // error

上記のエラーは、二つのcircleが同じスコープに存在するためです。 enumについては、次と等価です:

#define circle 0
#define retangle 1
そのため、後からcircleを定義するとエラーになります。

つまり、列挙名が同じかどうかにかかわらず、その中のメンバに一つでも重複があると問題が発生します。 例:

enum A {a,b};
enum B {c,a};
aが二回出現し、enum Bのaの箇所でエラーになります。

先ほど述べたように、enumの名前はスコープの面では何の役割も果たさないため、namespaceを思いつきます。次の例です:

// 在创建枚举时,将它们放在名称空间中,以便可以使用有意义的名称访问它们:
namespace EntityType {
    enum Enum {
        Ground = 0,
        Human,
        Aerial,
        Total
    };
}

void foo(EntityType::Enum entityType)
{
    if (entityType == EntityType::Ground) {
        /*code*/
    }
}
名前空間に意味のある名前を付ければ、望む効果を得ることができます。

しかし、絶えず名前空間を使うのはどうしても煩雑ですし、namespaceを使わずに同じ効果を得ようとすると、安全でなくなり、制約もなくなります。

そこで、C++11以降ではenum classが導入されました。

enum class は、enumメンバへの型定義、型安全性、制約といった問題を解決します。 先ほどの例に戻ると:

// enum class
enum class EntityType {
    Ground = 0,
    Human,
    Aerial,
    Total
};

void foo(EntityType entityType)
{
    if (entityType == EntityType::Ground) {
        /*code*/
    }
}
これがこの節で説明するイディオム、enum class です。

関連トピック

コメント