Читать «Эффективный и современный С++. 42 рекомендации по использованию С++11 и С++14» онлайн - страница 52
Скотт Мейерс
enum Color {black, white, red}; // black, white, red находятся
// в той же области видимости,
// что и Color
auto white = false; // Ошибка! white уже объяв-
// лено в этой области видимости
Тот факт, что эти имена перечисления “вытекают” в область видимости, содержащую определение их enum
, приводит к официальному термину для данной разновидности перечислений:
enum class Color
{ black, white, red }; // black, white, red принадлежат
// области видимости Color
auto white = false; // OK, других white нет
Color с = white; // Ошибка! Нет имени перечисления
// "white" в этой области видимости
Color с = Color::white; // OK
auto с = Color::white; // OK (и соответствует совету
// из раздела 2.1)
Поскольку enum
с областью видимости объявляются с помощью ключевого слова class
, о них иногда говорят как о
Снижение загрязнения пространства имен, обеспечиваемое применением перечислений с областью видимости, само по себе является достаточной причиной для предпочтения таких перечислений их аналогам без областей видимости. Однако перечисления с областью видимости имеют и второе убедительное преимущество: они существенно строже типизированы. Значения в перечислениях без областей видимости неявно преобразуются в целочисленные типы (а оттуда — в типы с плавающей точкой). Поэтому вполне законными оказываются такие семантические карикатуры:
enum Color {black, white, red}; // Перечисление без
// области видимости
std::vector<std::size_t> // Функция, возвращающая
primeFactors(std::size_t x); // простые делители x
Color с = red;
…
if (с < 14.5) { // Сравнение Color и double (!)
auto factors = // Вычисление простых делителей
primeFactors(c); // значения Color (!)
}
Добавление простого ключевого слова class
после enum
преобразует перечисление без области видимости в перечисление с областью видимости, и это — совсем другая история. Не имеется никаких неявных преобразований элементов перечисления с областью видимости в любой другой тип:
enum class Color // Перечисление с областью видимости
{black, white, red};
Color с = Color::red; // Как и ранее, но с квалификатором
// области видимости
if (с < 14.5) { // Ошибка! Нельзя сравнивать
// Color и double
auto factors = // Ошибка! Нельзя передавать Color в