30

As we know, incrementation and decrementation of enum in C++03 is illegal, because C++03 enum may not be continuous. But the C++11 standard introduced the new enum class construction, which, according to Wikipedia, is more type-safe because it isn’t built on any simple countable type. So now, if we have a bounded list of values of an enum, can we write something like

enum class Colors { Black, Blue, White };
// ...
Colors color = Colors::White;
color++;

and will it work correctly (e.g. incrementation of White will return Black and decrementation of Black will return White)?

If we can't write such code, do you know any behavior-like classes either from boost or from Qt that provide us this feature (correct in- and decrementing)?

9
  • 1
    There's nothing to say that the values of class enums are contiguous. In this respect, they are the same as C++03 enums. Commented Mar 16, 2013 at 15:18
  • possible duplicate of Using enum in loops and value consistency Commented Mar 16, 2013 at 15:20
  • 2
    @juanchopanza: C++03 enums most certainly inherit the C behavior that values are assigned sequentially. Each enum item without an initializer is the previous item + 1. If the first has no initializer, it will have the value zero. This is completely guaranteed and standard, and has been ever since there was a Standard. see Section 7.2p2 Commented Mar 16, 2013 at 15:33
  • 3
    Who told you that enum class isn't built on a base integral type? The only difference is that now you can optionally choose the base type yourself, instead of the compiler doing it in an implementation-dependent way. Commented Mar 16, 2013 at 15:38
  • 1
    The range of representable values for a enum is always continuous. Which values in that range are given explicit names and which are not is completely irrelevant. The fact that one can't use the above operators with enum objct has nothing to do with its continuity. Commented Feb 2, 2019 at 20:14

1 Answer 1

39

will it work correctly

No. enums are not designed to "wrap around" in the way you describe by default.

And C++11's enum class doesn't guarantee contiguous values, the same as you describe for C++03's enum.

You can define the wrapping behavior for your particular enum though. This solution assumes that the values are contiguous, like the enum you described.

enum class Colors { Black, Blue, White, END_OF_LIST };

// Special behavior for ++Colors
Colors& operator++( Colors &c ) {
  using IntType = typename std::underlying_type<Colors>::type
  c = static_cast<Colors>( static_cast<IntType>(c) + 1 );
  if ( c == Colors::END_OF_LIST )
    c = static_cast<Colors>(0);
  return c;
}

// Special behavior for Colors++
Colors operator++( Colors &c, int ) {
  Colors result = c;
  ++c;
  return result;
}
Sign up to request clarification or add additional context in comments.

13 Comments

How does this cope with non-contiguous values?
@juanchopanza only in that we can observe that there are none.
Is there a way to implement ++ without casts? I can't think of any, but this implementation bothers me. Casts are usually indication of something wrong and there has to be a very good reason for their usage. I would expect the language to allow implementation of ++ to be achievable without forcing to a specific type.
And what about non-contiguous enum class? Iteration over a range of allowed values is a very natural operation and I don't see a way to achieve it even with casts.
@icepack That's because there isn't. enums are, for that reason, not a particularily useful construct in most situations.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.