C++ FAQ Celebrating Twenty-One Years of the C++ FAQ!!!
(Click here for a personal note from Marshall Cline.)
Section 29:
[29.19] What is the type of an enumeration such as enum Color? Is it of type int?

An enumeration such as enum Color { red, white, blue }; is its own type. It is not of type int.

When you create an object of an enumeration type, e.g., Color x;, we say that the object x is of type Color. Object x isn't of type "enumeration," and it's not of type int.

An expression of an enumeration type can be converted to a temporary int. An analogy may help here. An expression of type float can be converted to a temporary double, but that doesn't mean float is a subtype of double. For example, after the declaration float y;, we say that y is of type float, and the expression y can be converted to a temporary double. When that happens, a brand new, temporary double is created by copying something out of y. In the same way, a Color object such as x can be converted to a temporary int, in which case a brand new, temporary int is created by copying something out of x. (Note: the only purpose of the float / double analogy in this paragraph is to help explain how expressions of an enumeration type can be converted to temporary ints; do not try to use that analogy to imply any other behavior!)

The above conversion is very different from a subtype relationship, such as the relationship between derived class Car and its base class Vehicle. For example, an object of class Car, such as Car z;, actually is an object of class Vehicle, therefore you can bind a Vehicle& to that object, e.g., Vehicle& v = z;. Unlike the previous paragraph, the object z is not copied to a temporary; reference v binds to z itself. So we say an object of class Car is a Vehicle, but an object of class "Color" simply can be copied/converted into a temporary int. Big difference.

Final note, especially for C programmers: the C++ compiler will not automatically convert an int expression to a temporary Color. Since that sort of conversion is unsafe, it requires a cast, e.g., Color x = Color(2);. But be sure your integer is a valid enumeration value. If you go provide an illegal value, you might end up with something other than what you expect. The compiler doesn't do the check for you; you must do it yourself.