eyt*
Feb 11, 2007

C++ Strongly-Typed Enumerations...

With the release on Java 5, we finally have enumerations in Java, but they really outdone themselves, in that an enumerated type is actually a class, where you can add your own methods. Take, for example, this code:

  1. public enum Color {
  2.   Red,
  3.   Yellow,
  4.   Orange,
  5.   Green,
  6.   Blue,
  7.   Brown,
  8.   Black,
  9.   Purple;
  10.  
  11.   public boolean isPrimaryColor() {
  12.     switch ( this ) {
  13.     case Red:
  14.     case Blue:
  15.     case Yellow:
  16.       return true;
  17.  
  18.     default:
  19.       return false;
  20.     }
  21.   }
  22. }

Instead of having a utility class off to the side that takes an enumeration as a parameter, you can now add that method directly to the enumeration, and I do not think that there would be much controversy that color.isPrimaryColor(); reads better than ColorUtils.isPrimaryColor( color );.

Putting this aside for a moment, C++09 is cleaning up their enumerations by adding support for strongly type enums (PDF Proposal).

In the current version of C++, we have problems with code like this:

  1. enum Color { RED, YELLOW, ORANGE, GREEN, BLUE, BROWN, BLACK, PURPLE };
  2. enum TerrorAlertLevel { RED, ORANGE, YELLOW, BLUE, GREEN };

This does not compile, because by the time it gets to TerrorAlertLevel, RED, ORANGE, YELLOW, BLUE, and GREEN are already defined, thanks to the Color enumeration. And worst off, if you have a coding standard that does not require you to have your enumerations all in caps (which makes sense, since part of the reason that Macros are usually done in caps is to discourage their use), then you could have an issue with any variables, such as int red = 0xFF0000; would not compile if the enumeration was all in lower-case.

As such, developers in C++ tend to add a prefix to the definition, such as:

  1. enum Color { COLOR_RED, COLOR_YELLOW, COLOR_ORANGE, COLOR_GREEN, COLOR_BLUE, COLOR_BROWN, COLOR_BLACK, COLOR_PURPLE };
  2. enum TerrorAlertLevel { TAL_RED, TAL_ORANGE, TAL_YELLOW, TAL_BLUE, TAL_GREEN };

Oh, that looks friendly.

Well, to help in that friendliness, C++09 is adding strongly typed enums. This is done by adding the class keyword to the enum definition. For example, the first C++ example above could compile under C++09 as this:

  1. enum class Color { RED, YELLOW, ORANGE, GREEN, BLUE, BROWN, BLACK, PURPLE };
  2. enum class TerrorAlertLevel { RED, ORANGE, YELLOW, BLUE, GREEN };

The bold emphasizes the difference.

Conceptually, I think this is a great addition to C++, making it easier to reuse enumerations and avoiding the crazy compilation errors that you can get if you accidentally name your variable a name that has already been defined in an enum.

The part that I do not like about this proposal, however, is the fact that it uses the keyword class but it is not a class. You cannot add member functions to it, which because of the power of the Java enumerations, I think this is confusing for developers which experience with Java enumerations.

C# enumerations are strongly typed but you cannot add any methods to them. But at least, they do not use the word class in their definition.

While I more than welcome the strongly-typed nature of enumerations in C++, I think that the implementation could have overloaded a better keyword than class. Since it does seem like this has been accepted already, hopefully a future version of the standard will add the ability to add member functions to the enumeration, minimizing some of this confusion.

Filed In

Navigation

eyt*