Чтобы понять причины, по которым два синтаксиса не являются допустимыми, вы должны учитывать, что перечисления с областями видимости были введены со стандартом c ++ 11 для обеспечения статической проверки типов и имеют идентификаторы областей (т. Е. Больше не загрязняется имя).
Foo foo(1)
не работает, поскольку неявное преобразование из целочисленного типа в перечисление с областью действия запрещено, в противном случае вы теряете преимущество перечислений с областью действия и избегаете конфликтов при разрешении перегрузки.
При использовании Foo foo{1}
вы используете инициализацию списка , которая была также введена с c ++ 11, но получила обновление с c ++ 17, которое состоит в неявном преобразовании из значения int в enum, как сообщается здесь , если набор требований удовлетворен:
И типы перечисления с областью действия, и типы перечисления с незаданной областью, базовый тип которых фиксирован, могут быть инициализированы из целого числа без преобразования, используя инициализацию списка, если всеверно следующее:
инициализация - прямая инициализация списка
список инициализаторов содержит только один элемент
перечисление либо ограничено, либо ограничено с фиксированным базовым типом
преобразование не является узкимING.
Это позволяет вводить новые целочисленные типы (например, SafeInt), которые используют те же существующие соглашения о вызовах, что и их базовые целочисленные типы, даже на ABI, которые штрафуют передаваемые / возвращаемые структуры по значению.
Этот синтаксис является безопасным и не будет мешать устаревшему коду (написанному до c ++ 11), потому что в то время не существовало ни перечислений области действия, ни инициализации списка.Кроме того, как сообщается в цитате, это позволяет использовать новые целочисленные типы (например, типы из библиотеки SafeInt) без необходимости принудительного статического приведения типов перечислений в коде, который соответствует современному синтаксису c ++.