如何使用枚举类值作为 for 循环的一部分?

新手上路,请多包涵

我正在尝试通过迭代枚举 SuitRank 来创建一副牌(我知道没有很好的方法来迭代枚举,但我没有看到替代方案) .我通过在每个枚举的末尾添加一个枚举 enum_count 来做到这一点,其值表示枚举的长度和结尾。

 #include <vector>

using namespace std;

enum class Suit: int {clubs, diamonds, hearts, spades, enum_count};
enum class Rank: int {one, two, three, four, five, six, seven, eight,
                nine, ten, jack, queen, king, ace, enum_count};

struct Card {
    Suit suit;
    Rank rank;
};

class Deck{
    vector<Card> cards{};
    public:
        Deck();
};

Deck::Deck() {
    // ERROR ON THE BELOW LINE
    for (Suit suit = Suit::clubs; suit < Suit::enum_count; suit++) {
        for (Rank rank = Rank::one; rank < Rank::enum_count; rank++) {
            Card created_card;
            created_card.suit = suit;
            created_card.rank = rank;
            cards.push_back(created_card);
        };
    };
};

但是,当我尝试遍历枚举时,编译器不喜欢我尝试在 for 循环中增加 suit++rank++ ,说明:

 card.cpp|24|error: no ‘operator++(int)’ declared for postfix ‘++’ [-fpermissive]|
card.cpp|25|error: no ‘operator++(int)’ declared for postfix ‘++’ [-fpermissive]|

在不丢弃有用的枚举数据结构的情况下创建一副纸牌的最佳方法是什么?

原文由 DBedrenko 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.1k
2 个回答

我会建议做一些不同的事情。创建一个 Suit 和一个到 Rank 的向量,并使用 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};

是的,你必须输入两次,但这允许你使用你想要的任何值(即不连续),而不是使用像 enum_count (你想要什么卡?给我一个diamonds enum_count!!),不需要强制转换,并使用提供给 std::vector 的迭代器。

要使用它们:

 for(const auto & s : v_suit)
    for (const auto & r : v_rank)
        cards.push_back({s,r});

原文由 hlscalon 发布,翻译遵循 CC BY-SA 3.0 许可协议

您可以将 suitrank 变量转换为 int& 并像这样增加它们。

     for (Suit suit = Suit::clubs; suit < Suit::enum_count; ((int&)suit)++) {
        for (Rank rank = Rank::one; rank < Rank::enum_count; ((int&)rank)++) {

然而,这可能会导致一些问题,例如当您为枚举条目分配值时。


您还可以创建一个小函数,使用正确的类型为您执行此操作:

 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);
        };
    };
};

原文由 Simon Kraemer 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题