Re[3]: преобразование одного enum в другой в C++ 14
От: DiPaolo Россия  
Дата: 04.09.24 19:21
Оценка: 9 (1) +3
S>я сейчас так и делаю
S>но надеялся что есть лучше вариант

нету лучше. Класс – это тип. Ты не можешь просто так преобразовать один тип в другой, без конвертации и описания бизнес-логики преобразования. Насильная топорная конвертация через static_cast чревата ошибками и не соответствует ООП-идеологии языка, которую в нее закладывал автор. Ну не может компилятор за тебя решить, как смаппить язык программирования в цвет для отображения цветных баров графика популярности языков программирования. То, что там Python будет иметь под собой циферку 2, а розовый цвет тоже будет иметь циферку 2 – не значит, что ты именно так хочешь смаппить. Думаю понятно объяснил логическую ошибку тут.
Патриот здравого смысла
Re: преобразование одного enum в другой в C++ 14
От: B0FEE664  
Дата: 04.09.24 13:10
Оценка: +4
Здравствуйте, sergey2b, Вы писали:

S>Подскажите пожалуйста как преобразовать одного enum в другой в C++ 14

enum class EColor
{
  red,
  green,
  blue
};

enum class EPlant
{
  spruce,
  poppy,
  gentiana_verna
};

inline EPlant convert(EColor color)
{
  switch(color)
  {
     case EColor::red  : return EPlant::poppy;
     case EColor::green: return EPlant::spruce;
     case EColor::blue : return EPlant::gentiana_verna;
  }
  assert(false);
  return EPlant::poppy;
}

И каждый день — без права на ошибку...
Re: преобразование одного enum в другой в C++ 14
От: vopl Россия  
Дата: 04.09.24 13:05
Оценка: 6 (1) +1 :)
Здравствуйте, sergey2b, Вы писали:

S>Подскажите пожалуйста как преобразовать одного enum в другой в C++ 14


используй static_cast
Re: преобразование одного enum в другой в C++ 14
От: Кодт Россия  
Дата: 05.09.24 11:10
Оценка: 12 (2)
Здравствуйте, sergey2b, Вы писали:

S>Подскажите пожалуйста как преобразовать одного enum в другой в C++ 14


Есть два аспекта: синтаксический и семантический. Как написать и что написать.

В семантическом есть два способа: логический и наивный.
Наивный — это любые варианты статик-каста (а по сути, реинтерпрет). Просто приводишь один underlying числовой тип в другой и скрещиваешь пальцы, что логика сохранилась.
Логический — это отображение одних числовых значений на другие. И вот тут начинается веселье. Можно свитчем, можно таблицей. Ещё вопрос, насколько устойчивы наборы значений в том и другом энуме (от версии к версии исходного кода), и как обрабатывать ошибки.

В синтаксическом есть два способа: инлайновое выражение и внешняя функция.
Неявное приведение через конструктор или оператор — для энумов невозможно.

Инлайновое выражение — это
static_cast<TargetEnum>(static_cast<std::underlying_type_t<TargetEnum>>(source_enum))

и оно работает, конечно, только для наивного преобразования.

Функция — тут уж свобода творчества
TargetEnum to_target_enum(SourceEnum source_enum) {
  switch(source_enum) {
    case SourceEnum::aaa : return TargetEnum::AAA;
    case SourceEnum::bbb : return TargetEnum::BBB;
    ...
    default: PANIC()
  }

  static const std::unordered_map<SourceEnum, TargetEnum> map{
    {SourceEnum::aaa, TargetEnum::AAA},
    {SourceEnum::bbb, TargetEnum::BBB},
    ...
  };
  return map.at(source_enum);

  using SourceInt = std::underlying_type_t<SourceEnum>;
  using TargetInt = std::underlying_type_t<TargetEnum>;
  auto source_int = static_cast<SourceInt>(source_enum);
  // на самом деле, тут условие гораздо более корявое и громоздкое, оно должно учитывать знаковые-беззнаковые сочетания всех сортов
  assert(std::numeric_limits<TargetInt>::min() <= source_int && source_int <= std::numeric_limits<TargetInt>::max());
  return static_cast<TargetEnum>(source_int);
}


Если энумы описаны на каком-то внешнем DSL (например, в протобуфе), то можно прибегнуть к имеющимся там средствам кодогенерации и рефлексии.
Перекуём баги на фичи!
Re[5]: преобразование одного enum в другой в C++ 14
От: Stanislav V. Zudin Россия  
Дата: 04.09.24 14:49
Оценка: 10 (2)
Здравствуйте, sergey2b, Вы писали:

S>у меня несколько enum на 15+ значений, функция выглядит странно

S>послезавтра кто то добавит новое значение в один из enum и забудит исправить функцию

У gcc есть полезный флаг

-Wswitch

Warn whenever a switch statement has an index of enumerated type and lacks a case for one or more of the named codes of that enumeration. (The presence of a default label prevents this warning.) case labels outside the enumeration range also provoke warnings when this option is used (even if there is a default label). This warning is enabled by -Wall.

-Wswitch-enum

Warn whenever a switch statement has an index of enumerated type and lacks a case for one or more of the named codes of that enumeration. case labels outside the enumeration range also provoke warnings when this option is used. The only difference between -Wswitch and this option is that this option gives a warning about an omitted enumeration code even if there is a default label.


Решение для Студии есть здесь:
https://stackoverflow.com/questions/32419201/enum-missing-cause-compiler-to-error
_____________________
С уважением,
Stanislav V. Zudin
Re[5]: преобразование одного enum в другой в C++ 14
От: DiPaolo Россия  
Дата: 04.09.24 19:26
Оценка: 6 (1) +1
S>у меня несколько enum на 15+ значений, функция выглядит странно
S>послезавтра кто то добавит новое значение в один из enum и забудит исправить функцию

я обычно пишу коменты в начале и в конце (на случай разрастания енумов, чтобы комент был виден при вставке и в начало, и в конец) каждого из енумов, мол, при добавлении поправь другой енум и/или функцию конвертации

Плюс, вставляю ассерты, что кол-во элементов в енумах равно
Патриот здравого смысла
Re[3]: преобразование одного enum в другой в C++ 14
От: B0FEE664  
Дата: 04.09.24 13:44
Оценка: 9 (1)
Здравствуйте, sergey2b, Вы писали:

S>я сейчас так и делаю

S>но надеялся что есть лучше вариант
А чем этот плох?

S>вот еще один способ https://www.geeksforgeeks.org/how-to-convert-enum-to-string-in-cpp/

Вообще-то это немного другая задача.
Вот конкретно для этой задачи есть множество способов разной степени безумия.
Тот, что по ссылке плох тем, что добавив новое значение в enum Color и забыв его добавить в map мы получим пустую строку после конвертации и изменение colorToString при использовании в функции enumToString. В свою очередь в многопоточном приложении это может привести к спорадическим падениям приложения.

В следующем стандарте C++26 может быть будет добавлена рефлексия, которая позволит писать метакод порождающий функции конвертации значения enum в строку.
И каждый день — без права на ошибку...
Re[4]: преобразование одного enum в другой в C++ 14
От: Alekzander  
Дата: 04.09.24 19:31
Оценка: -1
Здравствуйте, DiPaolo, Вы писали:

DP>То, что там Python будет иметь под собой циферку 2, а розовый цвет тоже будет иметь циферку 2 – не значит, что ты именно так хочешь смаппить.


Вообще-то, значит. Для чего бы иначе в языке была такая фича, как кастомные значения для членов енама? Делалась бы насильно нумерация с начала состава, и весь сказ. Так ведь, нет же.

Значения нужны, чтобы смапить енам на что-то внешнее. На флаги, например. А если ты дашь значения двум енамам, то смапишь их друг на друга. При этом, конечно, больше ты их ни на что не смапишь. Это как ковалентная связь в химии.
I'm a sewer mutant, and my favorite authors are Edgar Allan Poo, H.G. Smells and George R.R. Martin.
преобразование одного enum в другой в C++ 14
От: sergey2b ЮАР  
Дата: 04.09.24 12:55
Оценка:
Подскажите пожалуйста как преобразовать одного enum в другой в C++ 14
Re[2]: преобразование одного enum в другой в C++ 14
От: sergey2b ЮАР  
Дата: 04.09.24 13:23
Оценка:
Здравствуйте, B0FEE664, Вы писали:

я сейчас так и делаю
но надеялся что есть лучше вариант

вот еще один способ https://www.geeksforgeeks.org/how-to-convert-enum-to-string-in-cpp/
Re[4]: преобразование одного enum в другой в C++ 14
От: sergey2b ЮАР  
Дата: 04.09.24 14:42
Оценка:
Здравствуйте, B0FEE664, Вы писали:

S>>но надеялся что есть лучше вариант

BFE>А чем этот плох?

у меня несколько enum на 15+ значений, функция выглядит странно
послезавтра кто то добавит новое значение в один из enum и забудит исправить функцию
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.