Indexing with unscoped enums

When we access array elements using integral values as shown below:

std::cout << items[0] << "\n";

We do not know what items[0] mean. It lacks the code documentation. To address this, we can use enumerations as indexing values. For example:

#include <iostream>
#include <vector>
 
namespace Color
{
    enum Names
    {
        red,
        green,
        blue,
        max_color
    };
};
 
int main(int argc, char const *argv[])
{
    std::vector intensities{123, 223, 124};
 
    Color::Names color{Color::red};
 
    std::cout << intensities[Color::blue] << "\n";
    std::cout << intensities[color] << "\n";
 
    return 0;
}

intensities[Color::blue] makes clear that it will give intensity for color blue.

Count enumerator

We have used max_color enumerator in the above example for the purpose for noting the maximum number of enumerators present in the enumeration Color::Names. In this case, max_color is 3 (counting from 0). This max_color enumerator is called count enumerator as it counts the enumerators.

We can use this count enumerator to create array of a length equal to count of enumerators. This will make sure that the array length would always be valid and indexing with enumerator would never give out of index error (unless we have explicitly defined integral value to the enumerators).

For example:

std::vector<int> color_values(Color::max_color);
std::cout << color_values[Color::red] << "\n";

If we ever add more enumerators, we would not need to change the array code as count enumerator will increase and accordingly the array will be created.

Indexing with scoped enums

Scoped enumerators are not implicitly converted to integral types, we can’t directly use them for indexing. We need to explicitly convert them to integrals.

Doing so clutters the code. If there are many such conversions, better to go with unscoped enumerations inside namespace for indexing.

References

  1. https://www.learncpp.com/cpp-tutorial/array-indexing-and-length-using-enumerators/