7

For one who has never written a line of C++11, and who has, at the moment, no opportunity to program in C++11, can you, in one short paragraph., tell me:

What is an "enum class" and why do we need it?

Daniel Heilper
  • 1,182
  • 2
  • 17
  • 34
sbi
  • 219,715
  • 46
  • 258
  • 445
  • 1
    http://stackoverflow.com/questions/6936030/do-we-really-need-enum-class-in-c11 – user93353 Dec 26 '12 at 14:11
  • @user: I don't think that answers my two questions. – sbi Dec 26 '12 at 14:12
  • 1
    This is definitely a distinct question. The other questions (there are various) ask for a specific detail or the relationship to similar C++03 constructs. This is broader and would make a good FAQ question. – Potatoswatter Dec 30 '12 at 04:56
  • I'd say that the two questions are distinct but only marginally; the answer to this one that isn't in the other one is "read your C++11 book" -- no research performed. I'll vote to reopen, with a downvote. – Lightness Races in Orbit Jan 25 '13 at 15:16
  • Oh and if it became a [tag:c++-faq] question, I'd probably upvote instead. Because that's the crazy way the [tag:c++-faq] tag works, baby. – Lightness Races in Orbit Jan 25 '13 at 15:36

4 Answers4

15

enum class is called a scoped enumeration. It prevents polluting the namespace where the enumeration appears with the names of the enumerators.

In C++03, you could do effectively the same thing by putting the enum inside a dedicated class. Perhaps that's the source of the syntax, which is a bit confusing.

Another difference is that the enumerators of such a type don't convert implicitly to int (static_cast<int> is required). This may be seldom needed but it makes it safe to overload a function taking an int argument with one taking enum type. You can be sure the int won't be called by accident. Or you can define pseudo-integral types with dedicated operator functions, and be sure that built-in operators won't interfere.

It's a bit annoying that these two unrelated differences come in the same package, and that you can't get an unscoped enumeration with no implicit conversion, but generally both changes are Good Things and enum class is a good default practice in C++11.

EDIT: A scoped enumeration is defined like this:

enum class duck { huey, dewey, louie };

and must be used with the scope resolution operator :: like this:

duck culprit = duck::huey; // or "auto culprit" to avoid redundancy

Note that the :: operator also works with C++03 unscoped enumerations, so the second line above would work even if the first was missing class.

This might be excessive detail, but class does not go into the elaborated-type-specifier if forward declaring the enumerated type, as in

void quack( enum duck whom ); // not "enum class"

However, there is a construct new in C++11, the opaque-enum-declaration, which does include the class keyword and defines a complete type.

enum duck; // duck is declared as incomplete type
enum class duck; // duck is now complete type; underlying type defaults to int

The keyword struct can be substituted for class with no semantic difference.

Potatoswatter
  • 134,909
  • 25
  • 265
  • 421
  • 1
    Ah, finally what seems to be a good answer. Thank you, `+1` from me. Can you elaborate on the syntax? How do you define such a beast? I am sure I have seen it somewhere a few years ago, but I forgot. – sbi Dec 26 '12 at 14:47
  • @sbi not much to elaborate, you just add the `class` keyword to any `enum` definition and get these semantic changes. – Potatoswatter Dec 26 '12 at 15:01
  • Thanks, though, for still adding it. I feel like this answer is now a comprehensive explanation and I'll therefore accept it. (Although I won't promise to not to jump ship when something better comes along later. `:)` ) – sbi Dec 26 '12 at 16:27
  • Ahh, I see where I went wrong. I didn't explain myself very well. – happy coder Dec 26 '12 at 19:54
  • 1
    It's not actually legal in C++03 to add the enum qualification. I.e. `enum E { V }; E e = E::V;` is illegal in C++03. However some compilers such as VC++ allow this as an extension. C++11 makes this code legal though. – bames53 Jan 03 '13 at 19:44
  • 1
    @bames53 Yes, I meant that the `::` operator works with the unscoped enumerations carried over from C++03. – Potatoswatter Jan 04 '13 at 01:16
0
  1. You can explicitly specify the storage type when the data size is important (packing it in a struct perhaps).
  2. The enumeration values are scoped within the name of the enum only; before c++11 they leaked into the enclosing scope.
  3. I seem to recall the conversion rules were also changed somewhat...

In relation to point one 1, the storage size of enums would change before C++11 depending on the largest value assigned to an enumeration. Usually it doesn't matter so much, but when it does you have to resort to ugly hacks to force the size.

As for point 3, in C++11 enums are not implicitly convertible or comparable to ints or other enum types: useful for avoiding function overloading headaches and other implicit conversion gotchas.

Brandon
  • 724
  • 5
  • 12
  • After ruben's edit this is really promising. Now if you could only give a definite statement about #3, elaborate on all your points, rather than just #1, I'd be tempted to upvote. `:)` – sbi Dec 26 '12 at 14:27
  • 3
    `enum class` is not related to specifying the underlying type with `:`. – Potatoswatter Dec 26 '12 at 14:31
  • @Potatoswatter right, but specifying the underlying type without using `enum class` is only provided as a transitional syntax AFAIK. – Brandon Dec 26 '12 at 14:34
  • @sbi As for **3**, in C++11 `enum`s are not implicitly convertible or comparable to `int`s or other `enum` types. – Brandon Dec 26 '12 at 14:36
  • 2
    Transitional to what? Annex D (the standard's section on backwards compatibility features) doesn't mention anything about enumerations. – Potatoswatter Dec 26 '12 at 14:43
  • Transitional in that it allows you to use sized `enums` without the new scoping rules (well, really both the old and new scoping simultaneously). Probably to help with changing old code bases bit by bit. – Brandon Dec 26 '12 at 15:04
0

Personnally I have used it in a tcp based messaging protocol: many of the fields were enum values that I needed to encode inside one byte only, so as to respect the messaging interface..

All my enums were simply defined this way:

enum class EnumFieldA : unsigned char { eValProperty1, eValProperty2};
enum class EnumFieldB : unsigned char { eValProperty1, eValProperty2, eValProperty3};
enum class EnumFieldC : unsigned char { eValProperty1, eValProperty2, eValProperty3, eValProperty4};
...

there are also plenty of thorough answers in this SO question.

Community
  • 1
  • 1
Stephane Rolland
  • 38,876
  • 35
  • 121
  • 169
  • 1
    How does that answer what an `enum` class is? – sbi Dec 26 '12 at 14:26
  • 1
    It answers to your **and why do we need it?**. This is the **why** I needed it and the **how** I have used it. – Stephane Rolland Dec 26 '12 at 14:29
  • 2
    `class` is unrelated to specifying `unsigned char`, and you shouldn't serialize by transmitting the bytes of a structure *especially* over TCP (although if all the fields are one byte, that does avoid endianness issues). – Potatoswatter Dec 26 '12 at 14:45
  • I used an alignement of 1. And I supposed that it is the same endianness if both platforms have the same os, as it was the case for the system I worked on. – Stephane Rolland Dec 26 '12 at 14:47
  • However if you have links to best practices and advices regarding tcp, I'm nothing agaist it :-) – Stephane Rolland Dec 26 '12 at 14:49
  • 1
    Best practice: don't assume endianness. There's an RFC which specifies that big-endian (opposite to Intel) is the official endianness of internet binary transmissions, hence it's used in TCP packet headers and such. You can probably find the RFC linked on Wikipedia's page about endianness. – Potatoswatter Dec 26 '12 at 15:13
-1

At first I was confused by your question, but I think you want to know the difference between c++ enum and that in c++11. As best as I can understand, in the later, you have strongly typed enums which allows you to scope your them. I think this explains it well. CHEERS

happy coder
  • 1,517
  • 1
  • 14
  • 29
  • 1
    a lot of restrictions is not what you call "freedom" – Abyx Dec 26 '12 at 14:19
  • Abyx, perhaps you had a point. I was a bit inaccurate in my wording, but I think it is more in line with reality now. For the happy downvoter, you might want to check out the reference. I think it is a very useful link. – happy coder Dec 26 '12 at 19:51