There are many ways to iterate through consecutive enums like
enum Animal {Cat, Dog, Dolphin}
But is there a convenient and easy way to iterate through non-consecutive enum elements like
enum Animal {Cat = 0, Dog = 5, Dolphin = 8}
There are many ways to iterate through consecutive enums like
enum Animal {Cat, Dog, Dolphin}
But is there a convenient and easy way to iterate through non-consecutive enum elements like
enum Animal {Cat = 0, Dog = 5, Dolphin = 8}
The short answer to this is "no".
You could make a table animals
, and then use a range loop on animals
.
Here's a complete "demo":
#include <iostream>
using namespace std;
enum Animal {Cat = 0, Dog = 5, Dolphin = 8};
int main()
{
Animal animals[] = { Cat, Dog, Dolphin };
for(Animal a : animals) cout << a << endl;
}
The output will be:
0
5
8
You could also provide the necessary operator(s) for the enumeration:
enum Animal
{
Cat = 0
, Dog = 5
, Dolphin = 8
};
inline Animal& operator++ (Animal &x)
{
switch (x) {
case Cat:
x = Dog;
break;
case Dog:
x = Dolphin;
break;
case Dolphin:
default:
x = static_cast<Animal>(static_cast<int>(x) + 1);
break;
}
return x;
}
DTTO for postfix ++
, <
and anything else you need. Of course, you have to keep them in sync with the definition of the enumeration. Not really straightforward, but it is an option.
I'm not sure that the question even makes sense. It is at any rate fundamentally impossible. Consider:
enum Animal
{
cat = 0,
dog = 5,
dolphin = 8,
canine = 5,
bear = 20
};
When the underlying value is 5
, you have no way of determining
whether it was set by dog
or by canine
, and so no way of
knowing whether the next value should be dolphin
or bear
.
You could put the values in an array, and iterate over that, but
I don't see any other solution.
In general, of course, most of the time you're explicitly
affecting values like this this, you're defining a bitmask (e.g.
like std::ios_base::fmtflags
), and in that case, it makes no
sense to iterate. Other use cases I can think of would be
special sentinal values (e.g. something like unset
), which you
would probably want to skip when iterating, or synonyms (like my
dog
/canine
example above), in which case, you'd probably
only want to visit one of the synonyms, and realistically, you'd
write something like:
enum Animal
{
cat,
dog,
canine = dog,
dolphin,
bear
};
, and the usual iteration tricks would result in exactly what you want.