15

I have an enum class like this:

    typedef unsigned int binary_instructions_t;

    enum class BinaryInstructions : binary_instructions_t
    {
        END_INSTRUCTION = 0x0,

        RESET,

        SET_STEP_TIME,
        SET_STOP_TIME,
        START,

        ADD
    };

And I am trying to use the members of the enum in a switch statement like this:

const std::string& function(binary_instructions_t arg, bool& error_detect)
{
    switch(arg)
    {
        case (unsigned int)BinaryInstructions::END_INSTRUCTION:
            return "end";
        break;
    }
    translate_error = true;
    return "ERROR";
}

Why is the cast to (unsigned int) required when the underlying type is already an unsigned int?

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
FreelanceConsultant
  • 13,167
  • 27
  • 115
  • 225
  • if you pass the "right" type to function (BinaryInstructions), not the one that is underlying (binary_instructions_t) then you won't need a cast. – Freddie Chopin Feb 19 '13 at 21:55

2 Answers2

16

That's because "enum class" is "strongly-typed", so not implicitly convertible to any other type. http://en.wikipedia.org/wiki/C%2B%2B11#Strongly_typed_enumerations

Freddie Chopin
  • 8,440
  • 2
  • 28
  • 58
  • Perfect, thanks, but will this slow execution time? (As a matter of interest.) – FreelanceConsultant Feb 19 '13 at 21:49
  • No, it's a compile time check. – Bartek Banachewicz Feb 19 '13 at 21:51
  • It won't as that's just info for compiler - there is nothing to be done during runtime with such conversion (unless you specify a conversion operator that actually does something that requires computation). – Freddie Chopin Feb 19 '13 at 21:51
  • Just saying I think this is stupid. Compiler errors should stop us from accidentally doing something bad. I dont see how using the value of an enum in a integer can be bad. –  Jun 18 '19 at 01:11
  • Strongly typed derived classes should be implicitly convertible to their bases. I'm surprised this is different. I can comprehend that type in enum class x : uint8_t uint8_t should not convert to x, but x should at least be convertible to "it's base" – Werner Erasmus Oct 21 '19 at 05:58
15

Because C++11 strongly typed enums are not implicitly convertible to integral types by design. The fact that the underlying type is an unsigned int doesn't mean the type of the enum is unsigned int. It is BinaryInstructions.

But you don't actually need the conversion anyway Since arg is an unsigned int, you need a cast, but you should prefer a static_cast for clarity:

switch(arg)
{
    case static_cast<unsigned int>(BinaryInstructions::END_INSTRUCTION) :
        return "end";
    break;
}
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • Perfect, thanks, but will this slow execution time? (As a matter of interest.) – FreelanceConsultant Feb 19 '13 at 21:48
  • 1
    Will what slow execution time? And compared to what? – David Schwartz Feb 19 '13 at 21:49
  • Sorry, will the cast slow exec. time? – FreelanceConsultant Feb 19 '13 at 21:51
  • @EdwardBird I see, your function takes an unsigned int. Can it not take a `BinaryInstructions`? – juanchopanza Feb 19 '13 at 21:53
  • @juanchopanza I notice you made an edit... Why should I use static cast? – FreelanceConsultant Feb 19 '13 at 22:38
  • 1
    @EdwardBird it is both clearer (what it does is well defined) and easier to see and search for in code. C-style casts are not favoured in C++ for those seasons, and are only kept for backwards compatibility with C. In this particular case, it isn't very important though. – juanchopanza Feb 19 '13 at 22:40
  • @juanchopanza when you say both cleared, what do you mean by this? I did not realize c-style casts were obsolete in a sense. – FreelanceConsultant Feb 19 '13 at 22:41
  • @EdwardBird I meant both **clearer** and and easier to see. I am terrible at typing. – juanchopanza Feb 19 '13 at 22:42
  • @juanchopanza Thanks I will use c++ casts for future projects since it is considered good practice. – FreelanceConsultant Feb 19 '13 at 22:43
  • @EdwardBird: It won't *compile* without the cast. So how can you ask whether the cast will slow execution time? What is the execution time of code that doesn't compile? – David Schwartz Feb 19 '13 at 23:00
  • @DavidSchwartz, once again you are making a nuisance of yourself. One is to assume if I used an enum, or something which was not so strongly typed, then it would compile, and that is our comparison point. Failing this, the question is simply, does a type cast slow execution? – FreelanceConsultant Feb 19 '13 at 23:07
  • 2
    @EdwardBird: Can a type cast slow execution compared to what though? What is the baseline we're comparing it to? It would have to be some code that didn't have a type cast but was otherwise similar. It's not clear precisely what that would be, and the answer would depend on precisely what it was being compared to. It can't be the very same code without the cast because that doesn't compile. – David Schwartz Feb 19 '13 at 23:17
  • @juanchopanza: It is nonsensical to say that a change that allows code to compile that wouldn't otherwise compile has "no effect on execution time". (Sadly, you have now taught the OP something nonsensical and he now thinks he knows something when he doesn't.) What is true is that on any reasonable compiler (in sensible contexts), `static_cast(10)` should produce the very same compiled code as `10.0`. But `static_cast(sqrt(x))` can't be done at compile time. – David Schwartz Feb 19 '13 at 23:18
  • @DavidSchwartz I was simply stating that the `static_cast`'s work is done at compilation time. I wasn't considering any non-compiling alternative. But I see your point. – juanchopanza Feb 19 '13 at 23:22