How to iterate through enums

I've been trying to figure out how to use the advantages of enums over static const unsigned variables by creating objects with them like so:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
enum eSuit
{
    SPADES,    DIAMONDS,
    CLUBS,     HEARTS
};
enum eVal
{
    ACE = 1,	
    TWO,    THREE,    FOUR,    FIVE,
    SIX,    SEVEN,    EIGHT,   NINE,
    TEN,    JACK,     QUEEN,   KING
};

class cCard
{
public:
	cCard(eSuit s, eVal n) : suit(s), num(n) {}

	eSuit suit;
	eVal num;
};


okay, no problem so far. But now if I want to make a deck with these cards, I'd want to do something like this and get the following errors:
1
2
3
4
5
6
7
8
9
10
11
class cDeck
{
    std::list<cCard> deck;
public:
    cDeck()
    {
        for (eSuit suit = SPADES; suit <= HEARTS; ++suit)
            for (eVal num = ACE; num <= KING; ++num)
                deck.push_back( cCard(suit,num) );
    }
};
1>Snippets.cpp(7): error C2675: unary '++' : 'eSuit' does not define this operator or a conversion to a type acceptable to the predefined operator
1>Snippets.cpp(8): error C2675: unary '++' : 'eVal' does not define this operator or a conversion to a type acceptable to the predefined operator


so now if I try and do something like this, I get the following errors:
1
2
3
4
5
6
7
8
9
10
11
class cDeck
{
    std::list<cCard> deck;
public:
    cDeck()
    {
        for (unsigned suit = SPADES; suit <= HEARTS; ++suit)
            for (unsigned num = ACE; num <= KING; ++num)
                deck.push_back( cCard(suit,num) );
    }
};
1>Snippets.cpp(9): error C2665: 'cCard::cCard' : none of the 2 overloads could convert all the argument types
1>          Snippets.cpp(31): could be 'cCard::cCard(eSuit,eVal)'
1>          while trying to match the argument list '(unsigned int, unsigned int)'


So my question: What's the most effective way to iterate through enums? Do I need to use the unsigned type and just cast it to the enum type when sticking it in my constructor? It works, but I was wondering if there was a more native way to do it.
1
2
3
4
5
6
7
8
9
10
11
class cDeck
{
    std::vector<cCard> deck;
public:
    cDeck()
    {
        for (unsigned suit = SPADES; suit <= HEARTS; ++suit)
            for (unsigned num = ACE; num <= KING; ++num)
                deck.push_back( cCard( (eSuit)suit, (eVal)num) );
    }
};
Last edited on
I think I would create a macro definition to automatically create operators for my enums so I could do ++suit and such.
You can overload operator ++ for enumeration type.:)
I wonder if ++static_cast<unsigned int> (suit) would work.

Catfish2 (105)

I wonder if ++static_cast<unsigned int> (suit) would work


I did not check but in my opinion it shall not work because operator ++ requires lvalue.
@Stewbond

try something as

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
enum eVal
{
    ACE = 1,	
    TWO,    THREE,    FOUR,    FIVE,
    SIX,    SEVEN,    EIGHT,   NINE,
    TEN,    JACK,     QUEEN,   KING
};

eVal operator ++( eVal value )
{
	if ( value == KING ) return ( ACE );
	
	unsigned int x = value;
	return ( static_cast<eVal>( ++x ) );
}

Vlad is probably right, although I didn't check either.
Also following his suggestion; it's not pretty. Maybe someone has a better idea?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
enum Cards_e {
    SPADES,
    DIAMONDS,
    CLUBS,
    HEARTS
};

Cards_e operator ++ (Cards_e &c, int)
{
    switch (c)
    {
        case SPADES: c = DIAMONDS; return SPADES;
        case DIAMONDS: c = CLUBS; return DIAMONDS;
        case CLUBS: c = HEARTS; return CLUBS;
        case HEARTS: c = SPADES; return HEARTS;
        default: return c;
    }
}

closed account (zb0S216C)
I don't think iteration of an enumeration is allowed. Constants that are initialised with constant expressions, such as const int Constant(0), do not have memory allocated to them. Since each enumerator is assigned a magic constant by default, they won't have memory assigned to them. So how do you iterate through something that doesn't technically exist? Or have I got the wrong idea?

Wazzak
Hmm good points everyone. This is quite interesting. I'll try overloading the enums and see how "clean" I can make it, although I see Framework's point regarding constants. Perhaps the "right" idea is to static_cast the enum to an unsigned when iterating.
Last edited on
I'd probably wrap it in a class or something if you wanted to do that.
Topic archived. No new replies allowed.