Каков тип константы перечисления, когда она используется вне определения перечисления с незаданной областью?
Рассмотрим следующий код:
#include <iostream>
enum modes
{
begin = 0,
end = 1
};
int main()
{
std::cout << std::boolalpha
<< std::is_same<unsigned int, typename std::underlying_type<modes>::type>::value
<< std::endl;
std::cout << sizeof(modes) << std::endl;
std::cout << (-100 + end) << std::endl;
}
Это дает на моей машине:
true
4
-99
Теперь, если я только изменю значение какого-нибудь другого перечислителя, begin
в 2147483648
, тогда мой вывод становится:
true
4
4294967197
Видимо, это означает, что этот тип end
изменился с int
в unsigned int
даже базовый тип modes
остается прежним (т.е. unsigned int
).
Существуют ли какие-то особые правила для интегральных промо-акций, касающихся перечислений?
Из стандарта C ++ (7.2 Объявления перечисления)
- …После закрывающей скобки спецификатора перечисления каждый перечислитель имеет тип своего перечисления.…
И (4.5 Интегральные акции)
3 Значение типа перечисления с незаданной областью, базовый тип которого
не фиксированный (7.2) может быть преобразован в значение первого из
следующие типы, которые могут представлять все значения перечисления
(то есть значения в диапазоне от bmin до bmax, как описано в 7.2): int,
unsigned int, long int, unsigned long int, long long int или unsigned
длинный длинный инт. Если ни один из типов в этом списке не может представлять все
значения перечисления, prvalue типа перечисления с незаданной областью
может быть преобразовано в значение расширенного целочисленного типа с наименьшим
Целочисленный конверсионный ранг (4.13) больше ранга long long в
которые могут быть представлены все значения перечисления. Если там
Два таких расширенных типа, подписанный выбирается.
Каков тип константы перечисления, когда она используется вне определения перечисления с незаданной областью?
Это тип перечисления, конечно. Тип begin
является modes
, Если бы он имел целочисленный тип, ваш вопрос относительно целочисленного продвижения перечислений не имел бы смысла.
Существуют ли особые правила для целочисленных промо-акций с перечислениями?
На самом деле, нет. Вы думаете об интегральных продвижениях базового типа enum, но это нечто другое. Для самого типа enum вам нужно подумать о диапазоне допустимых значений типа enum, который может быть меньше диапазона допустимых значений базового типа enum. Можно int
может представлять все допустимые значения? Если это так, вы получите int
из этого.