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.7 -- Structs
S.4.5 -- Enumerated types

110 comments to S.4.5a — Enum classes

  • Nguyen


    In the first example, I have a question about "a and b" in the comment line 20.
    Below is line 20

    if (color == fruit) // The compiler will compare a and b as integers

    Do a and b in the comment mean color and fruit?

    My next question is line 12 in the third example.  
    Below is line 12.  

    if (color == Color::RED) // this is okay

    What is color's value now? since we know that "With enum classes, the compiler will no longer implicitly convert enumerator values to integers."


  • I see that you have omitted the comma (,) at the end of the second member of each of the above enum classes.  In the previous lesson it stressed that each member should have a comma after. Is this not so important in an ENUM Class?

    • Hi Nigel!

      > it stressed that each member should have a comma after
      The previous lesson says enumerators have to be separated by a comma, not followed.
      "Each enumerator is separated by a comma"
      Every enumerator, except the last one _has to_ be followed by a comma, the last enumerator _can be_ followed by a comma, but doesn't have to.

  • Tin

    So if i have two enum classes both of them have same BLUE enumerator will they be considered equal ?

    • nascardriver

      Hi Tin!

      You can't compare enumerators of different enum classes.
      If you cast the enumerators before comparison it depends on the value they have.

  • nascardriver

    Hi Alex!

    It might be worth mentioning that

    is equivalent to

    just in case anyone stumbles across this when reading through other code.

  • Lucas

    This one has me a bit confused, is there any scenario where using a standard enum is net beneficial to class enum's or should I just never use standard enums? Also, in your first example, what if one wanted to make an if statement saying like if(fruit::banana == color::yellow) with just class enums? I feel like one would would just use a class since fruit is more like an object instead of a property but for the purposes of the lesson ignore that.

    • nascardriver

      You> is there any scenario where using a standard enum is net beneficial to class enum
      Alex> 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.

      > should I just never use standard enums?
      I can't think of a good reason to use standard enums. Use enum classes.

      > what if one wanted to make an if statement [...]
      I don't see how this is a reasonable comparison, but you'd need to either cast them

      or define an operator to compare enums

    • Alex

      If you're declaring enumerations in the global scope, enum classes are superior for scoping reasons.

      However, I almost always use normal enums, not enum classes. This is because in practice I almost always define enums inside of a class, and the extra scoping of enum classes isn't needed in that context (the odds of enumerator collisions inside a single class are near-zero, and easy to fix if it does happen). I also most often use enumerators as array indices, and having to do the explicit conversion to convert the enumerator to an integer isn't wanted in that context.

  • Eri

    A few things:

    1) I find that i cant use std::cin so i could allow the user to decide which enum to use, is their a reason why?

    2)if enums are user defined data types do they have a range of how big an enumerator can be?

    3) Does direct initialization work better when dealing with enum classes?

    • nascardriver

      Hi Eri!

      1) C++ doesn't know how to convert a user input to an enum entry. Enum entry names are not present at run-time, they are replaced with numbers during compilation. You need to either ask the user to input an int and cast it to fit your enum or write a function that knows how to convert user input to your enum.

      2) The maximum amount of entries an enum can have is std::numeric_limits<size_t>::max() or 18446744073709551615.

      3) There shouldn't be a difference. Use uniform initializations whenever possible.

  • D.Master

    I actually learnt something new from you about basic C++ fundamentals. Never knew anything about class enumeration.

    However I like standard enums. They can be used in a switch statement.

    OK well enum class can be used in switch statement but for codes where namespace pollution is not a problem, less typing can be benefited from standard enumeration

  • Trevor

    Typo: in the second code example, "an scoped enumeration" should be "a scoped enumeration".

  • Mustafa

    i use cygwin "g++ compiler" on windows it support c++11 and few of c++14

    but there is something that went wrong, after creating enum class i try to initial value using scoping and every thing sounds good but it does not work correctly but compiler shows error and i have to cast to be able to make object of type color:

    photo link:

    • Alex

      It sounds like your version of g++ doesn't have full support for enum classes. Perhaps try upgrading your compiler to a newer version, or use a different compiler.

  • Harushi

    Hi Alex, in the previous lesson, you give an example

    In this Enum classes lesson, you said that the compiler will no longer implicitly convert enumerator values to integers. So I had to use the static_cast if I wanted to do the above example using enum classes instead. I think it's less convienient. Does it mean Enum classes is less useful than enumerated types?

    • Alex

      It simply means you should use the right tool for the job at hand. If you expect to be converting your enumerators to integers (e.g. because you're using them as array indices), maybe an enum is a better choice than an enum class.

  • Bernat

    Hi Alex,
    I have a lot of problems with enums, and I think it's because of my compiler but I don't really know. When I make an enum I get a warning that says "[Warning] non-static data member initializers only available with -std=c++11 or -std=gnu++11", and when I use an enum class apart from this warning I get another one that says "[Warning] scoped enums only available with -std=c++11 or -std=gnu++11", and I don't really know what neither of them mean. Besides, when I try to create a variable and initialize it with an enumerator from the enum class I get an error that says " 'Imaginary' is not a class or a namespace" (Imaginary is how I named my enum class) and I don't know what I'm doing wrong , because it's almost copied from your code, with the scope qualifier and everything. Btw, while I was writing this message I tried to change my code a few times, and the first warning disappeared (don't know why), so don't bother about it if it's unclear what I meant.
    Thanks for the attention.

    • Alex

      It sounds like maybe your compiler was confusing an enum class with a normal class. We talk about non-static data member initializers in the upcoming lesson in this chapter on structs.

      • Bernat

        Ok, so I've read that, and I guess that I can't use non-static initialization with my compiler right? But about the enum class part, does it mean that my compiler can't compile enum classes?

        • Alex

          It sounds like your compiler isn't C++11 compatible, or you haven't turned C++11 compatibility on. Both enum classes and non-static initialization are part of C++11.

          • Bernat

            It was this, thanks. I searched on google how to make my compiler c++11 compatible and it worked, thanks.

            • D.Master

              Anybody here use SFML (Simple Fast Multimedia Library)? I have developed a MenuBar class so that you can just add the  header file to your program and get access to a standard MenuBar with drop down box, ability to append your menu items to the MenuBar, and other useful MenuBar functionalities.

              Contact me at for the header files

  • Hi Alex,

    I am confused about "type(s)" in both enum classes & normal enumerations.

    Example 1: enum classes

    enum class Color

    enum class Fruit

    In this example 1, I've learned that Color and Fruit are different types.

    Example 2: normal enumerations

    enum Color

    enum Fruit

    Are Color & Fruit considered as the same the same type?

    Best regards,

    • Alex

      No, Color and Fruit are not the same type in example 2. You can see this by trying the following:

      The compiler will complain you can't assign a Fruit enumerator to a Color.

  • Kılıçarslan

    Hi,Alex! I'm in a trouble understanding this.

    This code works.

    But this doesn't.

    Even though FIRST is an integer,I can't print it with cout<<.If I don't use enum classes,it simply works with cout<<FIRST; I know variables of enum class can't get implicitly assigned but I assign them explicitly.Can you find a solution why this doesn't work?

  • Alfred O.

    I'm having a heck of a time trying to forward declare an enum. I downloaded the community version of Visual Studio (from 2015) to get a more up-to-date compiler, and despite what the book "C++ Primer" says about being able to forward declare an enum, I can't get it to work for me. According to that book, it should be as simple as typing:

    enum class Color : unsigned char;

    Into a header file and defining the enum somewhere else, like Color.cpp:

    enum class Color : unsigned char

    But it simply won't work. You may be able to declare an object of type Color, but you cannot initialize it or do much of anything, actually. I could figure out how to forward declare a class type, but not an enum? What madness is this?

    • Alex

      Forward declaring enums works like forward declaring any other type: the forward declaration tells the compiler that the type exists, but you can't actually do anything with it until you define it.

  • Ciccio

    I think that another important advantage of enum classes is that you can specify the underlying integer type:

    • Alex

      Thanks for teaching me something new! :)

      • Raquib


        Are you talking about the integer assigned to the enumerators???
        Makes sense when you have more than 2^32 enumerators int will no longer work.

        Another validation needed is- when we talk about global namespace, its just a concept right, kind of like the universal set, where enum class is a subset like namespace std is.......... and there isn't any specific namespace named global (namespace global{....; ...; }), of course there ain't one, else we would have accessed any global variable in it as "global::identifier" and not as  "::identifier", the blank signifies it being global.


        • Alex

          Yes, though I've never seen an enumeration with more than 255 enumerators, let alone 2^32.

          The global namespace is essentially the "outermost" namespace. It can contain inner namespaces (defined using enum classes, the namespace keyword, etc...). As you say, using the scope resolution operator with no prefix means the global namespace.

  • Manoj

    Can the enum items be accessed by index?
    Ex. cout << Color(1) << endl;

    • Alex

      What you're actually doing here is a C-style cast on integer 1, and casting it to an object of type Color. So you're not accessing it, you're converting it.

  • Lokesh

    It is written "When C++ compares color and fruit, it implicitly converts color to fruit to integers, and compares the integers."
    Is color converted to type fruit or both color and fruit are converted to integers?
    If the latter case is true, it should be
    "... it implicitly converts color and fruit to integers, ..."

  • There seems to be a problem which i cannot understand while trying to compile this code with the codeblocks(13.12). It says Fruit is not a class or a namespace.

  • ak

    I am not able to understand that why we are not using .h with the iostream ?

  • Jim

    For the third time (see above) I apologize if my earlier post was in error. I guess I'm a bit confused about namespace
    in the first code above your comment said enum Color and RED // RED is placed in the same namespace as Color.
    Then in the second your comment said enum class Color and RED, // RED is considered part of Color, not as part of the namespace that Color is in.

    I think of Color as a(custom)type,and Red as one of Color's elements. I can't imagine how they can be in the same namespace in the enum Color and not in the enum Class Color.

    Please clarify Thank You

    • Alex

      This is a hard concept to explain, so let me try again.

      Consider the following snippet of code:

      You'll agree that enum b is inside of namespace a, right? So we'd access it as a::b. With a normal enum, c and d are both also inside of a, so we'd access them as a::c and a::d. This is what I mean by the enumerators are in the same namespace as the enumeration.

      Now change the enum to an enum class. In this case, the enumeration is accessed via a::b. However, the enumerators are accessed as a::b::c or a::b::d.

      Note that the enumerators and the enumerations are no longer at the same level. The enumerators are inside the namespace of the enumeration.

      Now remove namespace a, and that's your normal case. In the normal enum case, b and c and d can be accessed directly. In the enum class case, b can be accessed directly, but c and d are still accessed as b::c and b::d.

      Make sense?

      • Jim

        Very good explanation Thanks

      • erad

        Nice explanation, Alex! Although I am reading this about 2 years later, I just have to applaud the pragmatic and illustrative manner by which you attempt to simplify otherwise hard or complex concepts. Please keep up the good work on these great and immensely helpful C++ tutorials!

  • Jim

    I've forgotten to provide an answer to the math above when I post quite a few comments. Then I loose all of the time and wording I've written.  Do you think someone can fix this to send us back to Leave a comment?

  • Jim

    Wait, how do the two enumerations Color and Fruit in the first example above get a value? In the last lesson you said values were assigned auto. to the elements in each enumeration but not the enumerations?  I see that there is a error in the code... if color == fruit) that may have something to do with it.

    Even if you could do this comparison don't the enum's., have to start with capital letter? (Color & Fruit)

    When you say "placed in the same namespace" in the first sentence just after the second code it's easy to confuse this with the keyword. Area might be better word there.
    LOL, no I'm not another Todd, it's that using keywords in descriptions can lead us new-bee's astray.

    • Alex

      Color and Fruit are enums declarations, so they don't have values themselves. They just specify what the enum looks like. The enumerators within those enumerations get mapped to a value. Since no explicit values have been assigned, the C++ compiler assigns values to the enumerators starting from 0 in sequential order (RED = 0, BLUE = 1, BANANA = 0, APPLE = 1).

      color and fruit are variables of the enum type Color and Fruit respectively. These work just like normal variables, and they can be assigned to, compared, etc... You can't compare Color and Fruit because they're just declarations (it would be like comparing int and float -- what does that even mean?).

      > When you say "placed in the same namespace" in the first sentence just after the second code it’s easy to confuse this with the keyword.

      I used the word "namespace" deliberately, but I've updated the article to talk about scopes instead of namespaces. With an enum class, the enumerator is defined inside the scope of the enumeration itself (which is why you have to use a scoping prefix to access it).

  • Anthony

    Do enum classes support using directives like namespaces do?

    For example, is there code similar to this that would work:

  • The Razer

    Can you suggest me a good IDE that supports c++11 ? (except visual studio)

  • R4Z3R

    How I can find out that my Compiler supports C++11 or not?

  • C++ newbie

    My code is not working.  I'm wondering if you can help me? I've deleted out some portions of code that I don't think pertain to the problem.




    Compiler error: error C2664: 'void printFruit(Fruit)' : cannot convert argument 1 from 'main::Fruit' to 'Fruit'

    Compiler error: IntelliSense: argument of type "Fruit" is incompatible with parameter of type "Fruit"

    • Alex

      Try moving enum class Fruit and Vegetable outside of function main().

      • C++ newbie

        Actually just entirely deleting the enum class Fruit from main fixed it.  What was wrong?  Was it that I declared the enum class twice because I had one in main, and one that i #included?

        • Alex

          I think because you declared Fruit inside of main, the version inside main hid the other version. Then when you tried to pass the version inside main to printFruit(), it tried to do a conversion from the Fruit inside of main to the other Fruit, and didn't know how (despite the fact that they're identical).

          • C++ newbie

            Dang, that's complex.  I've really been enjoying your support & the tutorial overall, though.  Thanks. (although I probably won't be using enums in my simple code!  structs seem cool though..)

  • Todd


    "(eg. Color::RED)" (you're missing a period between 'e' and 'g')

  • Connor

    Hello Alex.
    First - thank you so much for this tutorial. It is absolutely EPIC!

    WRT Josephs comment, I to was experiencing the same error on code::blocks. However, when I changed the compiler flags to “Have G++ follow C++11 ISO standard" it still won't compile but changes the error:

    cannot bind 'std::basic_ostream<char>' lvalue to 'std::basic_ostream<char>&&'.

    do you know if thee is a solution to this?
    Thanks again.

    • Alex

      Sorry Connor, I'm afraid this is beyond my knowledge. I'd definitely turn to the almighty Google for help on this one.

      Try searching for "code::blocks cannot bind ‘std::basic_ostream’ lvalue to ‘std::basic_ostream&&’." and see if you get any hits. Surely someone else has run into (and resolved) this issue before.

      • Chris

        I've been getting this as well. It seems to happen when I try to output an enum member(correct terminology?) directly as an integer. EG:

        Btw, thanks a million for this tutorial. It's pretty much the new gold standard haha.

        • Alex

          Oh, I see what's happening now that you've provided some context. With an enum class, the compiler won't do an implicit conversion from an enum class to an integer.

          All you need to do is use static_cast to cast your enum class variable (color) to an integer:

    • Jim

      Hey Conner,
      Your post is pretty old but if you clicked the box to use C++ 11 ISO it should cover all the new changes.

      Where did you come up with this code cannot bind ‘std::basic_ostream<char>’ lvalue to ‘std::basic_ostream<char>&&
      did you check it for typos?  What is it supposed to do?

  • There seems to be another difference in using enum and enum class (at least in C++11):

    And also this:

    • And furthermore this:

      Why? => Because strongly typed enums won’t convert to integers implicitly !
      So you need to use static_cast. I thought of that in the first place but I seemed to have made it incorrectly … so I thought, there must be another problem/difference. Now that’s sorted. However, this seems to make enum classes less convenient in a way.

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

      Well, one reason would be, if you’re tired of type casting.

  • Joseph

    Hi, I'm using the CodeBlocks that I downloaded a couple weeks ago, and it's saying that the class 'color' doesnt exist. I tried to make my own and when it failed, i copy pasted your code to see if it was me or the compiler, and yours failed too. How can I fix this?

    • Alex

      I'm guessing your compiler either isn't C++11 compliant, or has C++11 functionality turned off.

      I found this bit of advice on the web: "In code::blocks, go to project->build options->compiler settings->compiler flags and check "Have G++ follow C++11 ISO standard"

      Try that, and let me know if it works so I can update the tutorials.

Leave a Comment

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