Search code examples
c++indexingenumsc++17enum-class

How should we use an enum class for indexing (or should we better avoid this)?


Say we have an enum type foo which we want to use to index an array arr of static size.

If we want to use an enum class for this, we could try it like this:

enum class foo
{
    a,
    b,
    c,
    count
};

std::array<T, static_cast<int>(foo::count)> arr;

However, the count field is a hack. Can we obtain the number of fields of foo in a more elegant way?

In any case, what's really bad is that we need to access the array using a static_cast as well: arr[static_cast<int>(foo::a)].

Of course we could write a custom "at" function (see https://www.fluentcpp.com/2019/01/15/indexing-data-structures-with-c-scoped-enums/) or provide an "enum_array" class (see https://stackoverflow.com/a/55259936/547231), but both solutions are somehow complicated and we might better give up and use a simple std::array<T, int> instead ...

However, it's way more intuitive to read arr[foo::a] instead of arr[0], where we always need to remember what's the meaning of the index 0 in the latter.

Can we do better?


Solution

  • No, not really.

    There are many proposals that enable static reflection of enum values. None are in C++ yet.

    I mean you could do:

    namespace foo {
      enum value {
        a,b,c,count
      };
    }
    

    then the to int conversion is implicit, and you don't pollute the contained namespace.

    The solution here is pretty close to 0 overhead and lets you use enums (and only enums) as keys to [].

    So you get:

    enum_array<foo, T> arr;
    

    and arr behaves like you want it to.