5
enum class pid
{
    Alpha, Beta, Gamma
};

int main()
{
    int propId = 2;
    switch(propId)
    {
    case pid::Alpha:
    case pid::Beta:
    case pid::Gamma:
        break;
    }
}

Above snippet compiles fine in msvc2012 (and works) but fails in clang-3.4 and g++-4.8. These require static_cast<pid>(propId) to be used inside switch clause.

Incidentally, simple assignment without explicit cast such as pid a = propId; gives error in each compiler.

Which one got it right?

3
  • does it matter, either way you have to code around it Commented Jan 1, 2014 at 16:03
  • Although it compiles, Intellisense in VC++2013 marks it as an error. Commented Jan 1, 2014 at 16:08
  • AFAIK, Intellisense uses EDG compiler's frontend Commented Jan 1, 2014 at 16:45

1 Answer 1

6

The standard Clause 4, "standard conversions", only every lists unscoped enumerations. Therefore, strong enums do not have any standard conversions, and you must use the static_cast in either direction.

You could argue that this sort of explicitness is the entire point of the strong enums. They do not act as integers at the drop of a hat, but rather require explicit declaration of intent. Note [thanks, @DyP] that switch statements explicitly support strong enums and do not require a manual conversion to some integral type.

Sign up to request clarification or add additional context in comments.

6 Comments

You could also quote [stmt.switch].
Actually, it would be neat if the standard defined a static member at() that would convert an underlying-type value into the enum in question and throw a range exception.
@LightnessRacesinOrbit: No seriously - everyone and their dog reinvent wheels to validate and print enums. At least the validation part can be done better by the compiler than by reinvention, don't you think?
@KerrekSB: Yeah but I wish people wouldn't use enums like that at all. I see benefits when de-serialising and that's about it.
@LightnessRacesinOrbit Sometimes you are interfacing with other languages that do not have enums. You get an input integer, that you want to convert to an enum, cause you like to use those in your C++ code. Then you are force to use a switch statement, while something like template<typename EType> EType std::to_enum<EType>(typename std::unerlying_type<EType>::type i) would help..
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.