9

How should I loop over an enum class in C++11? I'm hoping I still don't have to add a final enum value of END but I couldn't get the range based looping to work either.

ildjarn
  • 62,044
  • 9
  • 127
  • 211
Xavier
  • 8,828
  • 13
  • 64
  • 98
  • 11
    An `enum` is not a container - it doesn't make sense to "loop" over it, IMHO. In any case, see the arithmetic part [here](https://bitbucket.org/martinhofernandes/wheels/src/c8e1b8979492/include/wheels/enums.h%2B%2B) for some example code that you could use. – Xeo Oct 03 '12 at 19:53
  • Related: https://stackoverflow.com/questions/8498300/allow-for-range-based-for-with-enum-classes – Adrian McCarthy Aug 27 '19 at 11:58

2 Answers2

4

If you really need to loop over enum class and you want to avoid adding special END symbol, you can define your own traits for this purpose.

template<typename E> struct EnumTraits;

enum class E { V1, V2, V3 };
enum class F { X1, X2, X3 };

template<> struct EnumTraits<E> { static constexpr E LAST = E::V3; };
template<> struct EnumTraits<F> { static constexpr F LAST = F::X3; };

Then you can write for example:

EnumTraits<E>::LAST 

to get "final" value of E. Of course you still need to define arithmetic operations on this class.

witosx
  • 614
  • 4
  • 15
  • 5
    Of course, this assumes the enum starts at 0 and doesn't skip any intermediate values. – Lily Ballard Oct 03 '12 at 20:36
  • 2
    @KevinBallard: ...Which is unlikely to be the case in many, many circumstances. – Ed S. Oct 03 '12 at 20:49
  • 1
    @EdS.: Depends on the purpose of the enum – Lily Ballard Oct 03 '12 at 20:53
  • 1
    @KevinBallard: Of course it does, hence the *"many, many circumstances"* bit. Point being this is not a reliable way to retrieve all values of an arbitrary enumeration. – Ed S. Oct 03 '12 at 21:02
  • 1
    @EdS.: Oh sorry, I misread what you said. You were agreeing with me, not disagreeing. Sorry for the confusion. – Lily Ballard Oct 03 '12 at 21:13
  • @KevinBallard: Yep, even upvoted your comment before I posted mine :D. Reading it again, I see how it could easily lead you to believe I was disagreeing. – Ed S. Oct 03 '12 at 21:24
  • @EdS. `std::underlying_type::type` extracts the, well, underlying type of the enumeration. With some help from numeric limits you can then iterate over all the values of said type, which covers all the possible values of the enumeration. It is not possible however to gather all *enumerators* of an enumeration, i.e. those named values. – Luc Danton Oct 04 '12 at 05:02
2

You can do processor hack like this:

#define E_INITIALIZER_LIST { E1, E2, E3, E4 }

enum E E_INITIALIZER_LIST;
constexpr E ALL_VALUES_OF_E[] E_INITIALIZER_LIST;
Isaac Pascual
  • 472
  • 2
  • 14
  • 1
    The list is a bit more flexible if you omit the braces from the macro. Then you can also add a `SENTINEL_VALUE`, put the list into round parentheses instead, etc. – Potatoswatter Jan 15 '18 at 20:01