In the external code that I am using there is enum:
enum En {VALUE_A, VALUE_B, VALUE_C};
In another external code that I am using there are 3 #define directives:
#define ValA 5 #define ValB 6 #define ValC 7
Many times I have int X which is equal to ValA or ValB or ValC, and I have to cast it to the corresponding value of En (ValA to VALUE_A, ValB to VALUEB, etc) because some function signature has enum En. And many times I have to do the opposite operation, translate enum En to ValA or ValB or ValC. I cannot change the signatures of these functions, and there are many such functions.
The question is: How to do the translation? Should I create 2 cast operators, which will be used implicitly? Or should I just have 2 translation functions which will be used explicitly:
En ToEn(int) int FromEn(En)
Or any other solution?
Since you can’t just cast here, I would use a free function, and if there are likely to be other enums that also need converting, try to make it look a little bit like the builtin casts:
Or something like that – might adjust it if issues arise while using it.
The reason I wouldn’t use implicit conversion is that there already is an implicit conversion from En to int, which gives the wrong answer. Even if you can reliably replace that with something which gives the right answer, the resulting code won’t look as though it’s doing any conversion. IMO this will hinder anyone who later looks at the code more than typing a call to a conversion routine will hinder you.
If you want converting to int and converting from int to look very different, then you could give the template and the function above different names.
Alternatively, if you want them to look the same (and more like a static_cast), you could do:
As written, T must have an implicit conversion from int. If you want to support T that only has an explicit conversion, use ‘return T(ValA);’ instead (or ‘return static_cast<T>(ValA);’, if you consider that single-arg constructors are C-style casts and hence impermissible).