You are here:

C++/enumuration values


could you plz tell me that are enumuration values coerced to integer?or are any other types coerced to an enumuration type?


Short answers are: Maybe and no, although coerce is probably not the correct term here.

Longer answer:

The values of an enumerated type (a.k.a. an enumeration) are called 'enumerators' in the ISO C++ standard.

During the defining of an enumerated type the type of an enumerator is the type of its initialiser value, or if there is no initialiser value the type of the preceding enumerator if that type can represent the incremented value of the preceding enumerator, otherwise it is an 'unspecified integral type sufficient to contain the incremented value'. If the first enumerator has no initialiser then it also has an 'unspecified integral type'. (the quoted parts are from the ISO C++ standard, 1998 edition).

So for example:

   unsigned char const BigestUChar(255); // assumes 8-bit unsigned char

   enum ExampleEnumType
   { first_enumerator          // No initialiser, type is an 'unspecified integral type' (value is 0)

   , second_enumerator = 10         // 10 is a literal int so type of enumerator is int

   , third_enumerator          // Value is 11 (10+1), enumerator type is int as 11 fits in an int

   , forth_enumerator = 1000L       // 1000L is a literal long int so type of enumerator is long int

   , fifth_enumerator = BigestUChar // BigestUChar is unsigned char so type of enumerator is unsigned char

   , sixth_enumerator          // Value is 256 (255+1); type is 'unspecified integral type sufficient
   };          // to contain the incremented value' as 256 cannot be represented by
         // 8-bit unsigned char

The full text of the paragraph in the ISO C++ standard containing this information (section 7.2 paragraph 4) is as follows:

       "Each enumeration defines a type that is different from all other types.
        Following the closing brace of an enum specifier, each enumerator has
        the type of its enumeration. Prior to the closing brace, the type of
        each enumerator is the type of its initializing value. If an initializer
        is specified for an enumerator, the initializing value has the same type
        as the expression. If no initializer is specified for the first enumerator,
        the type is an unspecified integral type. Otherwise the type is the same as
        the type of the initializing value of the preceding enumerator unless the
        incremented value is not representable in that type, in which case the type
        is an unspecified integral type sufficient to contain the incremented value."

OK so what happens when the definition is completed - after the closing brace of the enum specifier?

Well basically the integral type used for the enumerated type as a whole (called in the standard 'the underlying type') is one that can represent all of the enumerator values that are defined in the enumeration. This type is then used for all enumerators of the enumeration. The standard goes on the state that:

       "It is implementation defined which integral type is used as the underlying
        type for an enumeration except that the underlying type shall not be larger
        than int unless the value of an enumerator cannot fit in an int or unsigned

So that answers what values enumeration type enumerators have. However as they are part of a distinct type is not clear so far how they interact with other types. For this we look at the C++ standard conversion rules, where we find under integral conversions, that "An rvalue of an enumeration type can be converted to an rvalue of an integer type." Which basically means that enumerators will implicitly be converted to integer types for us by the compiler - of course the receiving integer type must be able to represent the underlying value of the enumerator.

However, the inverse is not true: there are _no_ such implicit conversions of integers to enumeration types.
To convert a value of an integer (or other) type to an enumerated type requires an explicit conversion (i.e. a type cast - preferably a static_cast if one has to be used at all).

Hence, whilst we can say:

   int intValue = third_enumerator;

We cannot say (following on from the previous example):

   ExampleEnumType enumValue = intValue;

We have to use an explicit conversion using a type cast in the latter case:

   ExampleEnumType enumValue = static_cast<ExampleEnumType>(intValue);

Of course type casting should be avoided if at all possible and their use is a red flag to anyone reading the code that something a little out of the ordinary or possibly dodgy is going on.

Another possibility would be to convert between objects of user defined class types and enumerations using user defined conversions (both single argument constructors and conversion operator member functions).

For example consider a class that can be used to convert to and from ExampleEnumType values and to std::string values. A quick and dirty implementation might look like so:

   class ExampleEnumTypeToString
       ExampleEnumType value_;

       ExampleEnumTypeToString( ExampleEnumType value )
       : value_(value)

       operator ExampleEnumType() const { return value_; }

       operator std::string() const
         switch (value_)
         case first_enumerator:  return "1st enumerator";
         case second_enumerator: return "2nd enumerator";
         case third_enumerator:  return "3rd enumerator";
         case forth_enumerator:  return "4th enumerator";
         case fifth_enumerator:  return "5th enumerator";
         case sixth_enumerator:  return "6th enumerator";
         default:          return "##Unknown enumerator##";

We can use the constructor to convert from ExampleEnumType values to ExampleEnumTypeToString objects and by using the operator ExampleEnumType() conversion operator from ExampleEnumTypeToString objects to ExampleEnumType enumeration values. We can also convert from ExampleEnumTypeToString objects to std::strings using the operator std::string() conversion operator. We can use ExampleEnumTypeToString like so:

   void Fn( ExampleEnumTypeToString const & v )
       std::string description( v );     // convert from ExampleEnumTypeToString to std::string
       ExampleEnumType enumerator( v );  // convert from ExampleEnumTypeToString to ExampleEnumType
       std::cout << description << " has value " << enumerator << std::endl;

   int main()
       int intValue = third_enumerator;
       ExampleEnumType enumValue = static_cast<ExampleEnumType>(intValue);

   // Call Fn with ExampleEnumType enumerator values, which are converted to
   // temporary ExampleEnumTypeToString objects using the single argument
   // constructor
       Fn( fifth_enumerator );
       Fn( enumValue );

Hope this answers what you were asking about.  


All Answers

Answers by Expert:

Ask Experts


Ralph McArdell


I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.


My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at


©2017 All rights reserved.