How to use enum class values as part of for-loop?
I would recommend doing something different.
Create a vector of Suit
and one to Rank
, and loop over them using the power of STL
const std::vector<Suit> v_suit {Suit::clubs, Suit::diamonds, Suit::hearts, Suit::spades};
const std::vector<Rank> v_rank {Rank::one, Rank::two, Rank::three, Rank::four, Rank::five,
Rank::six, Rank::seven, Rank::eight, Rank::nine, Rank::ten, Rank::jack,
Rank::queen, Rank::king, Rank::ace};
Yes, you have to type them twice, but this permits you to use whatever values you want for them (ie. not consecutive), not use awkward stuff like enum_count
(What card do you want? Give me a diamonds enum_count!!), no need for casting, and use the iterators provided to std::vector
.
To use them:
for(const auto & s : v_suit)
for (const auto & r : v_rank)
cards.push_back({s,r});
You could cast your suit
and rank
variables to an int&
and increase them as such.
for (Suit suit = Suit::clubs; suit < Suit::enum_count; ((int&)suit)++) {
for (Rank rank = Rank::one; rank < Rank::enum_count; ((int&)rank)++) {
Yet this might cause some problems like when you assign values to your enum entries.
You could also create a little function that does this for you with the correct type:
template <typename T>
T& increment(T& value)
{
static_assert(std::is_integral<std::underlying_type_t<T>>::value, "Can't increment value");
((std::underlying_type_t<T>&)value)++;
return value;
}
Deck::Deck() {
bool a = std::is_integral<std::underlying_type_t<Suit>>::value;
// ERROR ON THE BELOW LINE
for (Suit suit = Suit::clubs; suit < Suit::enum_count; increment(suit)) {
for (Rank rank = Rank::one; rank < Rank::enum_count; increment(rank)) {
Card created_card;
created_card.suit = suit;
created_card.rank = rank;
cards.push_back(created_card);
};
};
};