Подтвердить что ты не робот

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

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

enum e1 : int { x = 0, y = 1 };
enum class e2 : int { x = 0, y = 1 };

int main() {
        e1 foo = static_cast<e1>(42); // is this UB?
        e2 bar = static_cast<e2>(42);
}
4b9b3361

Ответ 1

Из n3290, 5.2.9 Статический литье [expr.static.cast]:

10 Значение интегрального или перечисляемого типа может быть явно преобразовано к типу перечисления. Значение не изменяется, если исходное значение находится в пределах значений перечисления (7.2). В противном случае результирующее значение не указано (и может быть не в этом диапазоне). [...]

Тип перечисления включает оба типа, объявленные с помощью enum, и те, которые объявлены с помощью enum class или enum struct, который Стандарт вызывает соответственно не облагаемые нумерацией перечисления и подсчеты с областью. Более подробно описано в 7.2. Объявления перечисления [dcl.enum].

Значения типа перечисления не следует путать с его счетчиками. В вашем случае, поскольку перечисленные вами перечисления имеют int как их базовые типы, их диапазон значений совпадает с диапазоном int: от INT_MIN до INT_MAX (включительно).

Так как 42 имеет тип int и, очевидно, значение int, то определяется поведение.