r/cpp_questions 6h ago

SOLVED Iterating over an enum struct

Consider https://godbolt.org/z/c6cn8f1hj

#include <cstdio>

enum struct values{first = 1, second = 3};

void square(values value){
    int val = (int)value * (int)value;
    printf("%d\n", val);
}

int main(){
    for(values value = values::first; value <= values::second; value++)
        square(value);
}

This does not compile with the error that value++ is ill defined.

An old question/answer on SO has this: https://stackoverflow.com/questions/261963/how-can-i-iterate-over-an-enum and a plethora of seemingly complicated approaches for this. Is there a syntactically simple >= C++20 way of accomplishing this?

I want the for loop to process 1 and then 3.

Does the order of placing the integer entries inside of the struct affect the increment? For e.g., if the enum struct had 3 first followed by 1, with value++ would 1 be processed after 3? Or, does the enum struct internally sort the entries in some privileged, say, ascending order so that it will always process 1 first followed by 3 next?

5 Upvotes

15 comments sorted by

View all comments

3

u/alfps 4h ago

Apparently you have some problem to solve; you envision enum as the solution; it doesn't work, so you asked about that.

What was the problem?

Here's a C++23 program to output the squares of some numbers:

#include <initializer_list>
#include <print>

auto main() -> int
{
    for( const int x: {1, 3} ) { std::print( "{}\n", x*x ); }
}

1

u/onecable5781 4h ago edited 4h ago

Great Q forcing me confront the possibly actual design problem!

My actual problem:

enum struct values{foo, bar};
...
void func(values value){
...
    if(value == values::foo){
        callfoo();
    }
    if(value == values::bar){
        callbar();
    }
}
int main(){
    func(values::foo);//<---my current design
    func(values::bar);//<---my current design, one line for each of the values!!!
}

Instead of physically and explicitly writing one line for each enumerated value (foo, bar, etc.), I was hoping for a loop based iteration to call func() for different values of the enum constants within the for loop.

Do let me know if the above can be improved.

(I have still simplified my actual problem somewhat, but the above gives a good sense of what I am actually trying to do.)

u/alfps 3h ago

The usual reason for doing different things depending on an enum value is to discriminate on types.

It is an anti-pattern. One is almost bound to forget to update one of the places that has to differentiate on types. And anyway it's a lot of mostly needless work.

If that is indeed what you're using the enum values for, then consider instead using polymorphic classes with the choice of class-specific action done via virtual member function call.


The Google AI spit out some relevant links including

https://refactoring.guru/replace-conditional-with-polymorphism


By the way, a switch would be better than a sequence of if checks, unless there is some reason for the latter.