enum class в switch case конструкций можно использовать если в switch стоит переменный с underlying type of enum

Raiden LuiKang
Raiden LuiKang

Пример, который не скомплируется в с++11 или слудующих версий, потому что enum color  не конвертируется на "int"  .  Но в switch case здесь никакое присваивание enum color  на каких либо int  не происходят. 

 

enum class color{ red, blue, white };

int main()
{
     int value = read_value_from_anywhere_other_library();

    switch( value ) 
    {
         case color::red :  printf("This is a red color\n"); break;
         case color::bllue : printf("This is a blue color\n"); break;
         case color::white : printf("This is a white color\n"); break;
         default: printf("This is not a color\n");
    }

    return 0;
}

 

Предлагаю, добавить  автогенерация оператор сравнение enum class  с его underlying type . Чтобы легко сравнивать и использовать их в if else , switch case  и других местах.

 

 

Тот пример , изменим и делаем работающий код для нынешного стандарт С++, будет UB:

enum class color{ red, blue, white };


int main()
{

    int value = read_value_from_anywhere_other_library();

   switch( (enum color) value ) // converting has a UB.
   {
       case color:: red: printf("This is a red color\n"); break;
       case color:: blue: printf("This is a blue color\n"); break;
       case color:: white: printf("This is a white color\n"); break;
       default: printf("This is a not color\n");break;
   }

}

 

Если не ошибаюсь, в с++17   конвертация целый число в enum class  будет UB,  если этот целый число значение имеет больше бит чем enum class элементы используется. В данном случий,  enum class color  -- элементам хватить 3 бит,  а  "value"  переменный может имет любой допустимый значений.

 

-1
рейтинг
4 комментария
Nate Reinar Windwood

Контрпродуктивно: вся суть enum class в строгой типизации. Если нужен только скоупинг — засуньте enum в неймспейс.

Nate Reinar Windwood
Raiden LuiKang

Nate Reinar Windwood,  enum class  очень удобно в компайл тайм вычеслениях,  а реальный пример где можно использовать его в рантайм есть?  Я свой проекте все enum ы перевел на enum class  и об этом сожелел, пришлось для каждого  enum class написать  операция сравнений на int  .  Конца, концов отказал от этий идей.

 

Raiden LuiKang
Raiden LuiKang
// Вот один пример.

struct table_row
{
    int id;
    int color;
};


enum class color{  red, blue, white } ;

void read_from_db(table_row& row)
{

    row =  read_from_outside_library();

    // Не комплириуется без  operator != (  int , enum color )  overload.

    if ( row.color != color::red && row.color != color::blue && row.color != color.white )
        throw std::runtime_error("row.color invalid");
}

Raiden LuiKang
Raiden LuiKang

Я не предлагаю,   изменить каких либо свойства enum class а. 

Предлагаю, implicit добавить  operation  == , !=   ,  < ,  > ,  <= , >=    с enum class  and its underlying-type.

 

Например, если вот эту компилятор сам генерирует, будет здорово!

 




template<  typename Enum > 
bool operator  == ( Enum e, typename std::underlying_type<Enum>::type value)
{
         return static_cast< typename std::underlying_type<Enum>::type > ( e ) == value ;
}

template<  typename Enum > 
bool operator  == (  typename std::underlying_type<Enum>::type value , Enum e)
{
         return static_cast< typename std::underlying_type<Enum>::type > ( e ) == value ;
}


 

Raiden LuiKang
Обновлено 
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).
Все предложения