Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

  1. Home
  2. C++ Dictionary
  3. enum

enum

In C++, enum (enumeration types) let you define related constants as a group. Since C++11, enum class (scoped enumeration) was added, enabling type-safe constants without polluting the surrounding namespace.

Syntax

// ========================================
// enum and enum class basic syntax
// ========================================

// Traditional enum (unscoped)
// Enumerators are exposed directly in the surrounding scope
enum InvestigationStatus {
    CLEAR,       // value 0 (assigned automatically)
    WATCHING,    // value 1
    SUSPECT,     // value 2
    TARGET       // value 3
};

// Explicit value assignment
enum SuspectLevel {
    LEVEL_LOW    = 1,
    LEVEL_MEDIUM = 50,
    LEVEL_HIGH   = 100
};

// enum class (scoped): C++11 and later
// Enumerators are accessed with the class name (type-safe)
enum class JudgementStatus {
    CLEAR,      // Access as JudgementStatus::CLEAR
    CAUTION,
    DANGEROUS,
    CRIMINAL
};

// Specify the underlying type (e.g., unsigned char)
enum class ThreatLevel : unsigned char {
    LOW    = 1,
    MEDIUM = 2,
    HIGH   = 3
};

// Usage
InvestigationStatus is = SUSPECT;              // Traditional enum (no prefix needed)
JudgementStatus     js = JudgementStatus::DANGEROUS;  // enum class (class name required)

Syntax Reference

Syntax / ConceptDescription
enum name { enumerator, ... }Defines a traditional unscoped enumeration. Enumerators are exposed in the surrounding scope and implicitly convert to int.
enum class name { enumerator, ... }Scoped enumeration type introduced in C++11. Enumerators must be accessed with the class name and do not implicitly convert to integers. Type-safe.
enum class name : type { ... }Specifies the underlying type (int, unsigned char, etc.) explicitly. Useful for memory optimization and binary compatibility.
enumerator = valueAssigns an explicit integer value to an enumerator. If omitted, the value is the previous enumerator + 1 (starting from 0).
static_cast<int>(enumerator)Converts an enum class value to an integer. Explicit cast is required because enum class prohibits implicit conversion.
Use with switch statementEnumeration types can be used as case labels in switch. Covering all enumerators lets you omit default and leverage compiler warnings.

Sample Code

deathnote_enum.cpp
// ========================================
// deathnote_enum.cpp
// Defines investigation statuses and evidence levels
// from DEATH NOTE using enum / enum class
// ========================================

#include <iostream>
#include <string>

// Traditional enum: InvestigationStatus
// No scope, so CLEAR etc. can be used without a prefix
enum InvestigationStatus {
    CLEAR    = 0,
    WATCHING = 1,
    SUSPECT  = 2,
    TARGET   = 3
};

// enum class: InvestigatorRole (type-safe)
enum class InvestigatorRole {
    LEAD,
    ANALYST,
    FIELD
};

// enum class: EvidenceLevel with unsigned char underlying type
enum class EvidenceLevel : unsigned char {
    WEAK   = 1,
    MEDIUM = 2,
    STRONG = 3
};

std::string statusLabel(InvestigationStatus status) {
    switch (status) {
        case CLEAR:    return "No suspicion";
        case WATCHING: return "Under observation";
        case SUSPECT:  return "Prime suspect";
        case TARGET:   return "Confirmed target";
        default:       return "Unknown";
    }
}

std::string roleLabel(InvestigatorRole role) {
    switch (role) {
        case InvestigatorRole::LEAD:    return "Lead investigator";
        case InvestigatorRole::ANALYST: return "Analyst";
        case InvestigatorRole::FIELD:   return "Field investigator";
        default:                        return "Unknown";
    }
}

std::string evidenceDesc(EvidenceLevel level) {
    switch (level) {
        case EvidenceLevel::WEAK:   return "Weak evidence — further investigation needed";
        case EvidenceLevel::MEDIUM: return "Moderate evidence — continue surveillance";
        case EvidenceLevel::STRONG: return "Strong evidence — warrant can be requested";
        default:                    return "Unknown level";
    }
}

struct Investigator {
    std::string         name;
    InvestigatorRole    role;
    InvestigationStatus status;
};

int main() {
    Investigator members[] = {
        { "Yagami Light", InvestigatorRole::LEAD,    WATCHING },
        { "L",            InvestigatorRole::LEAD,    CLEAR    },
        { "Amane Misa",   InvestigatorRole::FIELD,   SUSPECT  },
        { "Near",         InvestigatorRole::ANALYST, CLEAR    },
        { "Mello",        InvestigatorRole::FIELD,   WATCHING }
    };

    int memberCount = sizeof(members) / sizeof(members[0]);

    std::cout << "=== Kira Investigation Team — Status ===" << std::endl << std::endl;

    for (int i = 0; i < memberCount; i++) {
        const Investigator& inv = members[i];
        std::cout << "Name: " << inv.name << std::endl;
        std::cout << "  Role  : " << roleLabel(inv.role) << std::endl;
        std::cout << "  Status: " << statusLabel(inv.status) << std::endl;

        int roleInt = static_cast<int>(inv.role);
        std::cout << "  Role code: " << roleInt << std::endl << std::endl;
    }

    std::cout << "=== Evidence Levels ===" << std::endl << std::endl;
    EvidenceLevel levels[] = { EvidenceLevel::WEAK, EvidenceLevel::MEDIUM, EvidenceLevel::STRONG };
    for (int i = 0; i < 3; i++) {
        int val = static_cast<int>(levels[i]);
        std::cout << "Level " << val << ": " << evidenceDesc(levels[i]) << std::endl;
    }

    return 0;
}
g++ -std=c++11 deathnote_enum.cpp -o deathnote_enum
./deathnote_enum
=== Kira Investigation Team — Status ===

Name: Yagami Light
  Role  : Lead investigator
  Status: Under observation
  Role code: 0

Name: L
  Role  : Lead investigator
  Status: No suspicion
  Role code: 0

Name: Amane Misa
  Role  : Field investigator
  Status: Prime suspect
  Role code: 2

Name: Near
  Role  : Analyst
  Status: No suspicion
  Role code: 1

Name: Mello
  Role  : Field investigator
  Status: Under observation
  Role code: 2

=== Evidence Levels ===

Level 1: Weak evidence — further investigation needed
Level 2: Moderate evidence — continue surveillance
Level 3: Strong evidence — warrant can be requested

Common Mistake 1: Implicitly converting an enum class value to int

enum class prohibits implicit integer conversion, so directly comparing or using arithmetic with int causes a compile error.

// NG: Using enum class value implicitly as int
enum class EvidenceLevel { WEAK = 1, MEDIUM = 2, STRONG = 3 };
EvidenceLevel lv = EvidenceLevel::MEDIUM;
int val = lv;         // Compile error: implicit conversion not allowed
if (lv == 2) { }      // Compile error: cannot compare with int directly

OK: Use static_cast for explicit conversion.

// OK: Explicit conversion with static_cast
enum class EvidenceLevel { WEAK = 1, MEDIUM = 2, STRONG = 3 };
EvidenceLevel lv = EvidenceLevel::MEDIUM;
int val = static_cast<int>(lv);                 // 2
if (lv == EvidenceLevel::MEDIUM) { }            // Comparing enum class values is OK
g++ -std=c++11 enum_cast.cpp -o enum_cast
./enum_cast
EvidenceLevel::MEDIUM value: 2

Common Mistake 2: Name collision with traditional enum enumerators

Traditional enum enumerators are exposed without a scope prefix. If multiple enums have the same enumerator name, a compile error occurs.

// NG: Same enumerator name in multiple enums
enum InvestigationStatus { CLEAR, SUSPECT };
enum WeatherStatus       { CLEAR, CLOUDY };  // Error: CLEAR is ambiguous

OK: Switch to enum class to separate scopes.

// OK: enum class separates scopes
enum class InvestigationStatus { CLEAR, SUSPECT };
enum class WeatherStatus       { CLEAR, CLOUDY };

InvestigationStatus is = InvestigationStatus::CLEAR;
WeatherStatus ws       = WeatherStatus::CLEAR;  // No collision
g++ -std=c++11 enum_scope.cpp -o enum_scope
./enum_scope
Investigation status: No suspicion
Weather: Clear

Overview

Traditional enum is convenient because its enumerators are directly accessible in the surrounding scope, but it has drawbacks such as values from different enum types being mixed and implicit integer conversion. The enum class added in C++11 is a scoped enumeration type that requires the class name to access enumerators, preventing name collisions and detecting implicit integer conversions as compile errors. When an integer value is needed, use static_cast<int> for an explicit conversion. Specifying the underlying type with enum class name : type allows memory size optimization and binary compatibility. enum class is commonly used in newer code, but traditional enum remains an option when compatibility with existing code or simplicity is a priority. Combining with switch statements and variables / types enables safer and more readable constant management.

If you find any errors or copyright issues, please .