enum color {red, yellow, green}; // перечисление с не ограниченной

                                 // областью видимости

// безымянное перечисление с не ограниченной областью видимости

enum {floatPrec = 6, doublePrec = 10, double_doublePrec = 10};

Если перечисление является безымянным, определить объекты его типа можно только в составе определения перечисления. Подобно определению класса, здесь можно предоставить разделяемый запятыми список объявлений между закрывающей фигурной скобкой и точкой с запятой, завершающей определение перечисления (см. раздел 2.6.1).

Перечислители

Имена перечислителей в перечислении с ограниченной областью видимости подчиняются обычным правилам областей видимости и недоступны вне области видимости перечисления. Имена перечислителей в перечислении с не ограниченной областью видимости находятся в той же области видимости, что и само перечисление:

enum color {red, yellow, green}; // перечисление с не ограниченной

                                 // областью видимости

enum stoplight {red, yellow, green}; // ошибка: переопределение

                                     // перечислителей

enum class peppers {red, yellow, green}; // ok: перечислители

                                         // скрываются

color eyes = green; // ok: перечислители находятся в области видимости

              // для перечисления с не ограниченной областью видимости

peppers p = green; // ошибка: перечислители из peppers не находятся в

                   // области видимости

                   // color::green находится в области видимости,

                   // но имеет неправильный тип

color hair = color::red; // ok: к перечислителям можно обратиться явно

peppers p2 = peppers::red; // ok: использование red из peppers

По умолчанию значения перечислителей начинаются с 0, и значение каждого последующего перечислителя на 1 больше предыдущего. Однако вполне можно предоставить инициализаторы для одного или нескольких перечислителей:

enum class intTypes {

 charTyp = 8, shortTyp = 16, intTyp = 16,

 longTyp = 32, long_longTyp = 64

};

Как можно заметить на примере перечислителей intTyp и shortTyp, значение перечислителя не обязано быть уникальным. Без инициализатора значение перечислителя будет на 1 больше, чем у предыдущего.

Перечислители являются константами, и их инициализаторы должны быть константными выражениями (см. раздел 2.4.4). Следовательно, каждый перечислитель сам является константным выражением. Поскольку перечислители — константные выражения, их можно использовать там, где необходимы константные выражения. Например, можно определить переменные constexpr типа перечисления:

constexpr intTypes charbits = intTypes::charTyp;

Точно так же перечисление можно использовать как выражение в операторе switch, а значения его перечислителей как метки разделов case (см. раздел 5.3.2). По той же причине тип перечисления можно также использовать как параметр значения шаблона (см. раздел 16.1.1) и инициализировать статические переменные-члены типа перечисления в определении класса (см. раздел 7.6).

Подобно классам, перечисления определяют новые типы

Поскольку перечисление имеет имя, можно определять и инициализировать объекты этого типа. Объект перечисления может быть инициализирован или присвоен только одному из своих перечислителей или другому объекту того же типа перечисления:

open_modes om = 2;      // ошибка: 2 не имеет типа open_modes

om = open_modes::input; // ok: input - перечислитель open_modes

Объекты или перечислители типа перечисления с не ограниченной областью видимости автоматически преобразовываются в целочисленный тип. В результате они применимы там, где требуется целочисленное значение:

int i = color::red; // ok: перечислитель перечисления с не ограниченной

                    // областью видимости неявно преобразован в тип int

int j = peppers::red; // ошибка: перечисления с ограниченной областью

                      // видимости неявно не преобразуются

Перейти на страницу:

Похожие книги