In C++, Is it possible to enumerate over an enum (either runtime or compile time (preferred)) and call functions/generate code for each iteration?
Sample use case:
enum abc
{
start
a,
b,
c,
end
}
for each (__enum__member__ in abc)
{
function_call(__enum__member__);
}
Plausible duplicates:
I usually do that like this:
range
is completely generic, and defined like follows:Expanding on what Konrad says, one possible idiom in the case of "generate code for each iteration" is to use an included file to represent the enumeration:
mystuff.h:
enum.h:
main.cpp:
So, to add a new element "qux", you add it to mystuff.h and write the
do_qux
function. You don't have to touch the dispatch code.Of course if the values in your enum need to be specific non-consecutive integers, then you end up maintaining the enum definition and the
ENUM_ELEMENT(foo)
... list separately, which is messy.You can perform some of the proposed runtime techniques statically with TMP.
The output from this program is:
See Ch 1 of Abrahams, Gurtovoy "C++ Template Metaprogramming" for a good treatment of this technique. The advantage to doing it this way over the proposed runtime techniques is that, when you optimize this code, it can inline the statics and is roughly equivalent to:
Inline function_call for even more help from the compiler.
The same criticisms of other enumeration iteration techniques apply here. This technique only works if your enumeration increments continuously from a through end by ones.
Love templating but I'm going to make note of this for my future/other people's usage so we're not lost with any of the above.
Enums are convenient for the sake of comparing things in a known ordered fashion. They are typically used hard-coded into functions for the sake of readability against integer values. Somewhat similar to preprocessor definitions, with the exception that they are not replaced with literals, but kept and accessed in runtime.
If we had an enum defining html error codes and we knew that error codes in the 500s are server errors, it might be nicer to read something like:
than
The key part is this, they are similar to arrays! But are used to cast integer values.
Short example:
Oftentimes enums are also used with char* arrays or string arrays so that you could print some message with the associated value. Normally they're just arrays with the same set of values in the enum, like so:
And of course it's even nicer to create a generic class which handles iteration for enums like the answers above.
This seems hacky to me, but may suit your purposes:
If you need a special start value, you can make that a constant and set it in your enum. I didn't check if this compiles, but it should be close to being there :-). Hope this helps.
I think this approach might be a good balance for your use case. Use it if you don't need to do this for a bunch of different enumerated types and you don't want to deal with preprocessor stuff. Just make sure you comment and probably add a TODO to change it at a later date to something better :-).
Neither is possible without a little manual labour. A lot of the work can be done by macros, if you’re willing to delve into that area.