11

What exactly is the difference between:

typedef enum {
  something1,
  something2,
  .....
  somethingN
} myEnum;

end just

enum myEnum{
  something1,
  something2,
  .....
  somethingN
};

I know in first case I have typedefed unnamed enum, of course, just wonder which approach is better and why?

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • With C++11 now, you should use neither: `enum class` is safer. – leftaroundabout Mar 27 '12 at 15:52
  • 1
    @leftaroundabout While certainly an improvement, `enum class` is far from a complete replacement. It gives you two things (mandatory scoping, and no implicit conversions) but sometimes you want only one. – R. Martinho Fernandes Mar 27 '12 at 15:59
  • @leftaroundabout: This doesn't answer the original question. It only redirects it somewhere else. – SasQ Aug 12 '12 at 04:28

3 Answers3

19

The first variant was useful in C, because otherwise you would have to write enum myEnum everywhere you wished to use it.

This is not the case in C++. So, AFAIK, there is no benefit to the first case in C++ (unless you're defining e.g. an interface that needs to be shared with C).

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
16

No difference. In fact, the first version is C-style coding.

C++11 has introduced stronly-typed enum, which you define as:

enum class myEnum  //note the 'class' keyword after the 'enum' keyword
{   
  something1,
  something2,
  .....
  somethingN
};

In C++03, enums are not type-safe, they're essentially integers, and can mix with other integral types implicitly, and another problem with them is that they don't have scope; you can use its member without qualifying its type; you can use something1. Whereas C++11 strongly-typed enums are type-safe, and they've scope; you've to use myEnum::something1.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • 1
    It's not quite as bad as you suggest in C++03. Enums do define a distinct type, you can overload on them, and you can define overloaded operators using them. The implicit conversion to an integral type is a bit of a bother, but I've not found it to be a problem in practice. – James Kanze Mar 27 '12 at 15:59
  • @JamesKanze: Alright, I added the major problem with C++03 enums. Also, if they were not bad, then C++11 would not have added strongly-typed enums. – Nawaz Mar 27 '12 at 16:03
  • 1
    Scope was never a problem. `namespace scope_for_my_enum { enum { foo, bar }; }`, or `class scope_for_my_enum { enum { foo, bar }; };` depending on whether you want to allow clients to dispense with it. In fact, this means old enums *are more flexible* in terms of scoping. – R. Martinho Fernandes Mar 27 '12 at 16:06
  • 1
    @R.MartinhoFernandes: That is a workaround which tacitly admits the scoping-problem with C++03 enums, which is exactly why you came up with a workaround. Also, if you use such scoping workaround, the readability decreases a lot. – Nawaz Mar 27 '12 at 16:10
  • @Nawaz It proves it's not a *major* problem. It's just a nuissance. There is a simple workaround that even gives you more flexibility. The big problem with old enums is the implicit conversions *because there's no workaround for them*. – R. Martinho Fernandes Mar 27 '12 at 16:12
  • @R.MartinhoFernandes: Your earlier comment was not on "major". Anyway, I edited it. – Nawaz Mar 27 '12 at 16:14
  • 1
    I think that the main motivation is that people wanted the enum constants to be scoped (in some cases---not always). Beyond that, there is a general trend to less implicit conversions (although the horse is already out of the barn there). – James Kanze Mar 27 '12 at 17:18
1

I wouldn't use the first one. It is almost the same as the other one. In C++11, with the second you can write myEnum::something1 but not with the first one. Also in C++11, you can forward declare enums in some cases, but it is impossible to do forward declarations of unamed types and you can't forward declare typedefs either.

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510