Перечисления с областью видимости в C++, также известные как enum class или enum struct, представляют собой улучшенный подход к определению набора именованных констант. В отличие от обычных перечислений без области видимости, enum class обеспечивают локализацию своих элементов внутри определенной области видимости, что значительно снижает риск конфликтов имен и повышает безопасность кода.
Особенности перечислений с областью видимости (enum class):
- 
Локализация элементов: Элементы перечисления находятся в отдельной области видимости, что позволяет использовать одинаковые имена элементов в разных перечислениях и в других частях программы без опасения конфликтов имен. 
- 
Неявное преобразование: Элементы перечисления enum classнеявно не конвертируются в целочисленные значения, что уменьшает вероятность ошибок и улучшает безопасность.
- 
Использование в switch: Для перечислений с областью видимости требуется явное указание типа перечисления при использовании в конструкции switch.
- 
Защитные меры: Перечисления с областью видимости предотвращают неявное использование элементов в несвязанных контекстах и способствуют более ясному и понятному коду. 
Вот пример, который демонстрирует, как enum class (перечисление с областью видимости) обеспечивает безопасность и предотвращает конфликты имен, в то время как простое enum может привести к ошибкам из-за неявного преобразования и конфликтов имен:
#include <iostream>
using namespace std;
 
// Простое enum
enum Fruit {
    Apple,
    Orange,
    Banana
};
 
// enum class с областью видимости
enum class Color {
    Red,
    Green,
    Blue
};
 
void printFruit(Fruit f) {
    switch (f) {
        case Fruit::Apple:
            cout << "Fruit is Apple" << endl;
            break;
        case Fruit::Orange:
            cout << "Fruit is Orange" << endl;
            break;
        case Fruit::Banana:
            cout << "Fruit is Banana" << endl;
            break;
    }
}
 
void printColor(Color c) {
    switch (c) {
        case Color::Red:
            cout << "Color is Red" << endl;
            break;
        case Color::Green:
            cout << "Color is Green" << endl;
            break;
        case Color::Blue:
            cout << "Color is Blue" << endl;
            break;
    }
}
 
int main() {
    Fruit f = Fruit::Apple;
    Color c = Color::Green;
 
    // Пример работы с простым enum
    printFruit(f); // Ок
    // printFruit(c); // Ошибка компиляции: несоответствие типов, Fruit ожидается
 
    // Пример работы с enum class
    // printColor(f); // Ошибка компиляции: несоответствие типов, Color ожидается
    printColor(c); // Ок
 
    // Попытка присвоить значениям другого типа
    // f = 1; // Ошибка компиляции: несоответствие типов, Fruit ожидается
    // c = 1; // Ошибка компиляции: несоответствие типов, Color ожидается
 
    return 0;
}Объяснение:
- 
В простом enum(enum Fruit) элементы (Apple,Orange,Banana) находятся в общей области видимости, и они неявно конвертируются в целочисленные значения. Это может привести к ошибкам, если пытаться использовать их в функциях, ожидающих другие типыenumили целочисленные значения.
- 
В enum class(enum class Color) элементы (Red,Green,Blue) имеют собственную область видимости. Использование элементов требует явного указания типа перечисления. Это предотвращает неявное преобразование в целочисленные значения и повышает безопасность кода.
- 
В приведенном примере printFruit(f);вызывает ошибку компиляции, потому чтоFruitиColor- разные типы. Это не происходит сenum class, где компилятор считает,
Преимущества
- Более безопасное использование констант из перечисления, так как они неявно не конвертируются в целочисленные значения.
- Возможность использования одинаковых имен элементов в разных перечислениях и в других частях программы без конфликтов имен.
- Повышенная читаемость и понятность кода благодаря явной области видимости элементов перечисления.