Преобразование целочисленного типа в enum: функциональное приведение против инициализации - PullRequest
0 голосов
/ 27 апреля 2018

Предполагая, что есть перечисление как это:

enum foo: int {
    first,
    second
}

Тогда я использую его следующим образом:

foo f(1); // error: cannot initialize a variable of type 'foo' with an rvalue of type 'int'
foo f = foo(1); // OK !

Мне было интересно, в чем разница между этими двумя? Я понимаю, что вторую версию можно рассматривать как функциональный стиль, но почему это имеет какое-то значение?

Например, если я сделаю это:

class Bar {};
Bar b = Bar(1); // no matching conversion for functional-style cast from 'int' to 'Bar'

Я, очевидно, получаю ошибку, которая имеет смысл. Поэтому это заставляет меня поверить, что для работы второй версии приведенного выше примера foo должно быть преобразование из int в enum, определенное где-то, но если такое преобразование есть, то почему я получаю ошибку в первой версии?

Я прошу прощения, если это дубликат. Я подозреваю, что это так. Это кажется уместным: Это актерский состав или конструкция? ... но не бросить.

Заранее спасибо!

1 Ответ

0 голосов
/ 28 апреля 2018

Да, эти две формы довольно различны, тонким способом. Давайте посмотрим на первый, который приводит к ошибке. Это инициализация f, типа foo, из int. Здесь описано, мой акцент:

[dcl.init] /17.8

В противном случае начальное значение инициализируемого объекта (возможно преобразованное) значение выражения инициализатора. Стандартный преобразования будут использоваться, если необходимо , для преобразования инициализатора выражение для cv-неквалифицированной версии типа назначения; нет пользовательские преобразования рассматриваются. Если преобразование невозможно выполнено, инициализация некорректна .

Соответствующими преобразованиями в этом случае являются целочисленные преобразования, в основном, указанные следующим образом:

[conv.integral] / 1

Значение типа перечисления с незаданной областью можно преобразовать в prvalue целочисленного типа.

Таким образом, перечисление с незаданной областью может быть неявно преобразовано в целое число, но обратное неверно. Вот почему инициализация плохо сформирована. Однако эта нотация в функциональном стиле по сути является статической. И статическое приведение может выполнить (почти) любое допустимое стандартное преобразование . Таким образом, приведенный 1 затем используется для инициализации f, но на этом этапе мы инициализируем копию из значения foo, что, конечно, прекрасно.

...