Так как вы не можете просто привести здесь, я бы использовал бесплатную функцию, и, если есть вероятность, что есть другие перечисления, которые также нуждаются в преобразовании, попробуйте сделать так, чтобы это выглядело немного как встроенное приведение:
template<typename T>
T my_enum_convert(int);
template<>
En my_enum_convert<En>(int in) {
switch(in) {
case ValA: return VALUE_A;
case ValB: return VALUE_B;
case ValC: return VALUE_C;
default: throw std::logic_error(__FILE__ ": enum En out of range");
}
}
int my_enum_convert(En in) {
switch(in) {
case VALUE_A: return ValA;
case VALUE_B: return ValB;
case VALUE_C: return ValC;
// no default, so that GCC will warn us if we've forgotten a case
}
}
En enumValue = my_enum_convert<En>(ValA);
int hashDefineValue = my_enum_convert(VALUE_A);
enumValue = my_enum_convert<En>(0); // throws exception
Или что-то в этом роде - может настроить его, если при его использовании возникнут проблемы.
Причина, по которой я бы не использовал неявное преобразование, состоит в том, что уже является неявным преобразованием из En в int, что дает неправильный ответ. Даже если вы можете надежно заменить это на что-то, что дает правильный ответ, полученный код не будет выглядеть так, как будто он выполняет какое-либо преобразование. IMO, это будет мешать любому, кто позже будет смотреть на код больше, чем набирает вызов процедуры преобразования.
Если вы хотите, чтобы преобразование в int и преобразование из int выглядело совсем по-другому, вы можете присвоить шаблону и функции над разными именами.
В качестве альтернативы, если вы хотите, чтобы они выглядели одинаково (и больше как static_cast), вы можете сделать:
template<typename T>
T my_enum_convert(En in) {
switch(in) {
case VALUE_A: return ValA;
case VALUE_B: return ValB;
case VALUE_C: return ValC;
}
}
int hashDefineValue = my_enum_convert<int>(VALUE_A);
Как написано, T должен иметь неявное преобразование из int. Если вы хотите поддерживать T, который имеет только явное преобразование, используйте «return T (ValA);» вместо этого (или «return static_cast (ValA);», если вы считаете, что конструкторы с одним аргументом являются приведениями в стиле C и, следовательно, недопустимы).