Имеет ли перечислитель, используемый в выражении, тот же тип, что и базовый тип его перечисления?

Каков тип константы перечисления, когда она используется вне определения перечисления без области видимости?

Рассмотрим следующий код:

#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).

Существуют ли какие-то специальные правила для целостных промоушенов в отношении перечислений?


person Grzegorz Szpetkowski    schedule 13.07.2017    source источник


Ответы (2)


Из стандарта С++ (объявления перечисления 7.2)

  1. ... После закрывающей скобки спецификатора перечисления каждый перечислитель имеет тип своего перечисления....

И (4.5 Интегральные акции)

3 Значение prvalue типа перечисления с незаданной областью, базовый тип которого не является фиксированным (7.2), может быть преобразовано в значение prvalue первого из следующих типов, которые могут представлять все значения перечисления (т. е. значения в диапазоне от bmin до bmax как описано в 7.2): int, unsigned int, long int, unsigned long int, long long int или unsigned long long int. Если ни один из типов в этом списке не может представлять все значения перечисления, prvalue типа перечисления с незаданной областью может быть преобразовано в prvalue расширенного целочисленного типа с наименьшим целочисленным рангом преобразования (4.13), большим, чем ранг long long в котором могут быть представлены все значения перечисления. Если таких расширенных типов два, выбирается подписанный.

person Vlad from Moscow    schedule 13.07.2017
comment
может быть преобразовано в prvalue первого из следующих типов, которые могут представлять все значения перечисления. Это именно то, что я искал. Спасибо. - person Grzegorz Szpetkowski; 14.07.2017

Каков тип константы перечисления, когда она используется вне определения перечисления без области видимости?

Конечно, это тип перечисления. Тип beginmodes. Если бы у него был интегральный тип, ваш вопрос о интегральных продвижениях перечислений не имел бы смысла.

Существуют ли какие-то специальные правила для интегральных промоушенов с перечислениями?

Не совсем. Вы думаете о целостных продвижениях базового типа перечисления, но это нечто другое. Что касается самого типа перечисления, вам нужно подумать о диапазоне допустимых значений типа перечисления, который может быть меньше, чем диапазон допустимых значений базового типа перечисления. Может ли int представлять все допустимые значения? Если это так, вы получите int из этого.

person Community    schedule 13.07.2017