i On enums in C++ · Dark Matter Industries

On enums in C++

Enums are tremendously useful to group names in your namespace. In C++ an enum is basically a dictionary where the name that you declare in the enum is the key for an index value. By default this is a zero-index incrementing by one. Hence:

 enum gem_stones {
    Quartz,
    Ruby,
    Diamond,
    Jade,
 };

Here Quartz=0, Ruby=1, Diamond=2, Jade=3. 

But this default behaviour also leads to some logical problems. Say we define another set of enums later in the code:

 enum baby_names {
    Sarah,
    Leila,
    Jane,
    Annabelle,
 };

We will then have this ridiculous situation where:

 if ( Quartz == Sarah ) { 
    std::cout <<  Quartz == Sarah is True  << std::endl;
 } else {
    std::cout <<  Quartz == Sarah is False  << std::endl;
 }

Would compile and produce1:

 Quartz == Sarah is True

A work around from C++11 is to define the start of the index. Hence:

 enum gem_stones {
    Quartz = 20,  // 20
    Ruby,         // 21
    Diamond,      // 22
    Jade,         // 23
 };
  
 enum baby_names {
    Sarah = 30,   // 30
    Leila,        // 31
    Jane,         // 32
    Annabelle,    // 33
 };

That seems to solve the problem. But you have to track the indexing that you have used and if you use many enums in your code, there is still a risk of collision in the index number. 

C++11 also introduced enum Classes which solves that problem. If you think about it, a class is a collection of related names, functions etc. so it is perfectly logical that enums are a class. 

So the above examples would be written as:

 enum class gem_stones {
    Quartz,
    Ruby,
    Diamond,
    Jade,
 };

 enum class baby_names {
    Sarah,
    Leila,
    Jane,
    Annabelle,
 };

Now any gem_stones::Quartz == baby_names::Sarah comparisons will throw a compile error. It is far safer to catch these kinds of problems at compile time.


  1. In a modern g++, you will get a “comparison of different enumeration types” warning, and if you use an LSP interface, you will get a real-time warning, but the code will compile. ↩︎