Enum vs enum class C++11

What is the difference between enum and enum class in C++11? I think it is about type safety, but I need a better explanation.

Thanks in advance
Last edited on
You are right.

Before C++11, all enums were just, basically, integers. And you could use them like that. It made it too easy to give bad values to functions expecting a restricted set of values. For example:

1
2
3
4
5
6
7
8
9
10
enum round_mode { round_half_up, round_half_down, round_bankers };

double round( double x, round_mode = round_half_up )
{
   ...
};

int main()
{
  double x = round( 2.5, 42 );

It compiles, but it isn't pretty.

With C++11, the compiler now knows all kinds of things about your enums, and doesn't let you blithely mix them with incorrect values.

Essentially, it promotes an enum to a first-class object -- it isn't just an integer.


The other issue is that the name for each enumeration bleeds into the containing scope. So the following would be a name conflict:

1
2
enum color_masks { red = 0xFF0000, green = 0x00FF00, blue = 0x0000FF };
int red = 0xFF0000;

You can't have both the identifier 'red' as an enum value and as an integer variable name in the same scope.

While the example here is contrived, it isn't too far off from things that happen all the time -- and that programmers have to take pains to avoid.

(Some identifier names are common. For example, 'max'. If you #include <windows.h>, there's a 'max' macro in there, which plays havoc if you also #include <algorithm> and try to use the 'max' function, or #include <limits> and try to find the numeric_limit <int> ::max(). I know that's a macro problem, but it's the first name conflict I could come up with...)

There's more to read here:
http://www.stroustrup.com/C++11FAQ.html#enum

Hope this helps.
> Before C++11, all enums were just, basically, integers.

In C, enums were basically integers.

Even in C++98 a named enum was a distinct type; the underlying integral type is a suitable integral type that can represent the range of the enum. There was no implicit conversion from an int to an enum; this would not compile.
1
2
3
4
5
6
7
8
enum round_mode { round_half_up, round_half_down, round_bankers };

double round( double , round_mode = round_half_up ) ;

int main()
{
  round( 2.5, 42 ); // *** error: no implicit conversion from 'int' to 'round_mode'
}

http://coliru.stacked-crooked.com/a/959f2009eebed89b


In C++11, we can specify the underlying integral type of the enum (enum-base defaults to int for scoped enum):
1
2
enum colour : unsigned short{ RED, GREEN, BLUE }; // unscoped
enum class direction: unsigned short{ LEFT, RIGHT }; // scoped 

For unscoped enums, the enumerators are visible in the enclosing scope, and conversion to the underlying integer type is implicit.
For scoped enums, the enumerators are contained within the scope of the enum, and conversion to the underlying integer type is explicit.

We can have our pick:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
enum colour { RED, GREEN, BLUE }; // unscoped enum

struct printer { enum state { BUSY, IDLE, OFFLINE }; }; // unscoped enum at class scope

enum class direction { LEFT, RIGHT }; // scoped enum

int main()
{
    colour clr_sky = BLUE ;
    printer::state curr_state = printer::BUSY ;
    direction next_move = direction::RIGHT ;

    int a = clr_sky ; // imlicit conversion
    int b = printer::OFFLINE ; // imlicit conversion
    int c = int( direction::LEFT ) ; // explicit conversion

    clr_sky = colour(a) ; // explicit conversion
    curr_state = printer::state(b) ; // explicit conversion
    next_move = direction(c) ; // explicit conversion
}
Now I get it.

Thank you very much!
Topic archived. No new replies allowed.