Инициализация класса Enum по умолчанию - PullRequest
0 голосов
/ 22 декабря 2018

Определено ли поведение по умолчанию для инициализации / построения классов enum?

Вот минимальный пример ( Попробуйте онлайн )

enum class ALPHA{
    X = 0,
    Y = 1,
    Z = 2,
};

int main()
{
    ALPHA a = ALPHA(); // use default constructor
    ALPHA b{}; // use default initialization
    std::cout <<static_cast<int>(a) << std::endl; // 0
    std::cout <<static_cast<int>(b) << std::endl; // 0
    return 0;
}

Я получаю ноль в обоихслучаев.Так всегда ли инициализация по умолчанию выбирает первый тип перечисления (например, здесь X = 0) всегда?Я знаю, что это UB для стандартных перечислений, но я не уверен насчет семантики для классов перечислений?Я также посмотрел это на CPPReference , но не нашел никакой соответствующей информации об этом - возможно ли получить стандартную ссылку тоже?

Ответы [ 2 ]

0 голосов
/ 22 декабря 2018

[expr.type.conv] / 1 A спецификатор простого типа (10.1.7.2) или спецификатор типа (17,6), за которым следует необязательный * выражение-список в скобках или braced-init-list (инициализатор) создает значение указанного типа с учетом инициализатора.

[expr.type.conv] / 2 ... В противном случае выражение является prvalue указанного типа, чей объект-результат инициализируется напрямую (11.6) с помощью инициализатора.


[dcl.init] / (17.4) - Если инициализатор (), объект инициализируется значением.


[dcl.init] / 8 To value-initialize объект типа T означает:

(8.4) - в противном случае объект инициализируется нулями.


[dcl.init] / 6 Инициализация объекта или ссылки типа T с нуля означает:

(6.1)- если T является скалярным типом (6.9), объект инициализируетсяв значение, полученное преобразованием целочисленного литерала 0 (ноль) в T


[basic.types] / 9 ... типы перечисления... все вместе называются скалярными типами .

В совокупности ALPHA() эквивалентно static_cast<ALPHA>(0)

0 голосов
/ 22 декабря 2018
Перечисление

с фиксированным базовым типом может быть инициализировано с помощью initializer-list , если оно находится в контексте прямой инициализации и initializer-list содержит один элемент без сужающего преобразования.

[dcl.enum] / 8

[...] Можно определитьперечисление, значения которого не определены ни одним из перечислителей.

[dcl.init] /6.1

Инициализация объекта или ссылки типа T с нуля означает:

(6.1), если T является скалярным типом, объект инициализируется значением, полученным путем преобразования целочисленного литерала 0 (нуля) в T

Тем не менее, можно иметь перечисление, инициализированное значениями, которые не находятся в диапазоне его перечислителей, но когда оно попадает в диапазон, тогда оно соответствует перечислителю.

В вашем примере инициализация нуля инициализирует a и b вс 0, которые соответствуют перечислителю X, что означает ... ваш пример хорошо определен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...