Почему в C++17 перечисления с ограниченной областью нельзя преобразовать в целые числа без сужения с помощью инициализацC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Почему в C++17 перечисления с ограниченной областью нельзя преобразовать в целые числа без сужения с помощью инициализац

Сообщение Anonymous »

C++17 позволяет инициализировать перечисления с областью действия целыми числами, если они не сужаются, например

Код: Выделить всё

#include 
enum class e16 : uint16_t { x16, y16 };
enum class e32 : uint32_t { x32, y32 };

int main() {
e32{ uint16_t{} };       // okay
e32{ uint32_t{} };       // okay
e16{ uint16_t{} };       // okay
e16{ uint32_t{} };       // not allowed -- narrowing
}
Почему не наоборот? Я знаю, что перечисления с ограниченной областью действия не могут быть неявно преобразованы в целочисленные, но инициализация целочисленного значения {scoped_enum является явной, а C++ допускает использование области видимости_enum{ целое число , если оно не сужается.

Код: Выделить всё

#include 
enum class e16 : uint16_t { x16, y16 };
enum class e32 : uint32_t { x32, y32 };

int main() {
uint16_t{ e16{} };       // should be okay
uint16_t{ e32{} };       // narrowing
uint32_t{ e16{} };       // should be okay
uint32_t{ e32{} };       // should be okay
}
Обычно мне приходится использовать static_cast для преобразования перечисления с ограниченной областью в целое число, что допускает небезопасные сужающие преобразования.
Чтобы избежать сужения преобразований, я создал функцию приведения шаблона, использующую SFINAE:

Код: Выделить всё

#include 
#include 

template
inline constexpr INT enum_int_cast(ENUM e) { return static_cast( e ); }

enum class enum8  : uint8_t  {};
enum class enum16 : uint16_t {};
enum class enum32 : uint32_t {};
enum class enum64 : uint64_t {};

int main() {
enum_int_cast ( enum8 {} );    // okay
enum_int_cast ( enum16{} );    // not allowed -- narrowing
enum_int_cast ( enum32{} );    // not allowed -- narrowing
enum_int_cast ( enum64{} );    // not allowed -- narrowing

enum_int_cast( enum8 {} );    // okay
enum_int_cast( enum16{} );    // okay
enum_int_cast( enum32{} );    // not allowed -- narrowing
enum_int_cast( enum64{} );    // not allowed -- narrowing

enum_int_cast( enum8 {} );    // okay
enum_int_cast( enum16{} );    // okay
enum_int_cast( enum32{} );    // okay
enum_int_cast( enum64{} );    // not allowed -- narrowing

enum_int_cast( enum8 {} );    // okay
enum_int_cast( enum16{} );    // okay
enum_int_cast( enum32{} );    // okay
enum_int_cast( enum64{} );    // okay
}
Каково обоснование того, что C++17 разрешает не сужающие преобразованияscoped_enum{ целое , но не разрешает целочисленные{scoped_enum преобразования без сужения?
Я знаю, что инициализация фигурных скобок не вызывает явных конструкторов, поэтому может показаться, что использование фигурных скобок означает, что неявное преобразование невозможно, но это, похоже, исключает область видимости_enum{ целое число тоже.

Подробнее здесь: https://stackoverflow.com/questions/791 ... owing-by-u
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»