Каков базовый тип перечисления c ++? - PullRequest
35 голосов
/ 14 июля 2009

Возможно, на это ответили в другом месте, но я не смог найти подходящий ответ.

У меня есть этот код:

enum enumWizardPage
{
    WP_NONE = 0x00,  
    WP_CMDID = 0x01,    
    WP_LEAGUES = 0x02,  
    WP_TEAMS = 0x04,    
    WP_COMP = 0x08, 
    WP_DIVISIONS = 0x10,
    WP_FORMULAS = 0x20, 
    WP_FINISHED = 0x40, 
};

Что является устаревшим, и я должен изменить его, добавив несколько новых значений. Проблема заключается в том, что каждое значение должно быть уникальным битом, поэтому они могут быть объединены ИЛИ в битовый массив.

Значения устанавливаются с использованием шестнадцатеричного формата # x ##, но мне интересно, может ли это максимальное значение, которое он может хранить? Каков будет эффект, если таковой будет, если я изменю свой код на

enum enumWizardPage
{
    WP_NONE = 0x0000,  
    WP_CMDID = 0x0001,  
    WP_LEAGUES = 0x0002,    
    WP_TEAMS = 0x0004,  
    WP_COMP = 0x0008,   
    WP_DIVISIONS = 0x0010,
    WP_FORMULAS = 0x0020,   
    WP_FINISHED = 0x0040,   
};

Ответы [ 3 ]

41 голосов
/ 14 июля 2009

Тип перечисления C ++ - это само перечисление. Его диапазон довольно произвольный, но с практической точки зрения его базовый тип - int.

Он неявно приводится к int, где бы он ни использовался.

C ++ 11 изменений

Это изменилось со времен C ++ 11, который ввел типизированные перечисления. Нетипизированный enum теперь определяется как ширина не менее int (и шире, если требуются большие значения). Однако, учитывая типизированный enum, определяется следующим образом:

enum name : type {};

Перечисление типа name имеет базовый тип type. Например, enum : char определяет enum той же ширины, что и char вместо int.

Кроме того, enum можно явно определить следующим образом:

enum class name : type {
    value = 0,
    // ...
};

(где name требуется, но type является необязательным.) Объявленный таким образом enum больше не будет неявно приводиться к своему базовому типу (требующему static_cast<>), и на значения необходимо ссылаться с полностью квалифицированное имя. В этом примере, чтобы присвоить value переменной enum, вы должны ссылаться на нее как name::value.

38 голосов
/ 14 июля 2009

С N4659 C ++ 7,2 / 5 :

Для перечисления, базовый тип которого не является фиксированным, базовый тип является целочисленным типом, который может представлять все значения перечислителя, определенные в перечислении. Если ни один целочисленный тип не может представлять все значения перечислителя, перечисление неверно сформировано. Это определяется реализацией, какой интегральный тип используется в качестве базового типа, за исключением того, что базовый тип не должен быть больше int, если только значение перечислителя не может поместиться в int или unsigned int. Если список перечислителей пуст, базовый тип выглядит так, как если бы перечисление имело единственный перечислитель со значением 0.

1 голос
/ 14 июля 2009

IIRC его представляется как int в памяти. Но gcc имеет переключатель -fshort-enum, чтобы сделать его кратчайшим целочисленным типом, который соответствует всем значениям, если вам нужно сэкономить место. Другие компиляторы будут иметь что-то похожее.

...