Search

S.4.5a — Enum classes

Although enumerated types are distinct types in C++, they are not type safe, and in some cases will allow you to do things that don’t make sense. Consider the following case:

When C++ compares color and fruit, it implicitly converts color and fruit to integers, and compares the integers. Since color and fruit have both been set to enumerators that evaluate to value 0, this means that in the above example, color will equal fruit. This is definitely not as desired since color and fruit are from different enumerations and are not intended to be comparable! With standard enumerators, there’s no way to prevent comparing enumerators from different enumerations.

C++11 defines a new concept, the enum class (also called a scoped enumeration), which makes enumerations both strongly typed and strongly scoped. To make an enum class, we use the keyword class after the enum keyword. Here’s an example:

With normal enumerations, enumerators are placed in the same scope as the enumeration itself, so you can typically access enumerators directly (e.g. RED). However, with enum classes, the strong scoping rules mean that all enumerators are considered part of the enumeration, so you have to use a scope qualifier to access the enumerator (e.g. Color::RED). This helps keep name pollution and the potential for name conflicts down.

Because the enumerators are part of the enum class, there’s no need to prefix the enumerator names (e.g. it’s okay to use RED instead of COLOR_RED, since Color::COLOR_RED is redundant).

The strong typing rules means that each enum class is considered a unique type. This means that the compiler will not implicitly compare enumerators from different enumerations. If you try to do so, the compiler will throw an error, as shown in the example above.

However, note that you can still compare enumerators from within the same enum class (since they are of the same type):

With enum classes, the compiler will no longer implicitly convert enumerator values to integers. This is mostly a good thing. However, there are occasionally cases where it is useful to be able to do so. In these cases, you can explicitly convert an enum class enumerator to an integer by using a static_cast to int:

If you’re using a C++11 compiler, there’s little reason to use normal enumerated types instead of enum classes.

Note that the class keyword, along with the static keyword, is one of the most overloaded keywords in the C++ language, and can have different meanings depending on context. Although enum classes use the class keyword, they aren’t considered “classes” in the traditional C++ sense. We’ll cover actual classes later.

Also, just in case you ever run into it, “enum struct” is equivalent to “enum class”. But this usage is not recommended and is not commonly used.

S.4.6 -- Typedefs and type aliases
Index
S.4.5 -- Enumerated types

97 comments to S.4.5a — Enum classes

  • MisterNotMister

    Hi, what happens if you are using a struct or class
    and you define an enum inside it like as such.

    (dumb example, but is this also a right way of using enums?)
    EDIT: Why aren't code tags working for me???

    • That's perfectly fine. The only problem is that nested types can't be forward declared, which can quickly lead to circular dependencies. If the nested type is used by name outside of the class, don't declare it inside the class. If the nested type is only used internally or by returns, you can declare it inside of the class.

      > Why aren't code tags working for me?
      They stop working after editing a comment. They start working again when you refresh the page.

  • YB

    In C# there is ToString() for the enum values to get the name of the value in string format.

    Is there any plan to add the same functionality for C++ enum class?
    Are there any suggestions on how to achieve the functionality with what is currently available?

    • > Is there any plan to add the same functionality for C++ enum class?
      No

      > Are there any suggestions on how to achieve the functionality with what is currently available?
      You'll have to wait until arrays or containers have been covered. After chapter 6, you can use an array or `std::map` to map enumerators to strings.

      EDIT: You could use if-statements to check for all enumerators and return the corresponding name.

  • Q

    Enum classes seem like an utterly pointless addition. Instead of bending over backwards to disallow nonsensical comparisons, why not just trust programmers not to be idiots?

  • Pharap

    I've recently been reading the isocpp style guidelines and they advise against using ALL_CAPS for enumerators.

    http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Renum-caps

    Would the author(s) of the article consider possibly adopting some of the recommendations of this guide?
    In particular, not using all-caps for enumerators.

    This article is quite popular, so if it sets a good example then it will be responsible for future C++ programmers following good guidelines, which I think can only be a good thing.

  • Puya

    Hi, thanks as always for your helpful tutorials. Is this a typo "(e.g. it’s okay to use RED instead of COLOR_RED, since Color::COLOR_RED is redundant)"? Should it be "(e.g. it’s okay to use RED instead of Color::RED, since Color::RED is redundant)"?

  • B_H@cker

    В чем отличие "emun" от "class enum"?

  • Alaa Mahran

    Can you please elaborate more about this line: "If you’re using a C++11 compiler, there’s little reason to use normal enumerated types instead of enum classes.", I missed your point here! What is the relation between C++11 and enum classes and why it would be preferable in older versions but not in C++11?

  • Yaroslav

    Hello. may be i missed it somewhere.

  • C.E

    Alex, when  you mention strong typing rules, what do you exactly mean, from my research these  "rules" govern variable assignment and implicit type conversion. Reprhasing the question would be how these specefic rules function if I am using non-class based enumerators. In addition you speak of  the keyword class being overloaded(in what sense)

    • Alex

      "strong typing" in the context of an enum class means the enumerators live inside the scope of the type (rather than in the global scope) and thus must be prefixed by the type name to be accessible.

      The keyword class is more often used for creating user defined structs that have behaviors attached. Essentially the entirety of chapter 8 is about this.

Leave a Comment

Put all code inside code tags: [code]your code here[/code]