我只是注意到不能在枚举上使用标准数学运算符,如++或+=。

那么,在c++枚举中遍历所有值的最佳方法是什么?


当前回答

typedef enum{
    first = 2,
    second = 6,
    third = 17
}MyEnum;

static const int enumItems[] = {
    first,
    second,
    third
}

static const int EnumLength = sizeof(enumItems) / sizeof(int);

for(int i = 0; i < EnumLength; i++){
    //Do something with enumItems[i]
}

其他回答

我经常这样做

    enum EMyEnum
    {
        E_First,
        E_Orange = E_First,
        E_Green,
        E_White,
        E_Blue,
        E_Last
    }

    for (EMyEnum i = E_First; i < E_Last; i = EMyEnum(i + 1))
    {}

或者如果不是连续的,但有规则步长(例如位标志)

    enum EAnimalCaps
    {
        E_None    = 0,
        E_First   = 0x1,
        E_CanFly  = E_First,
        E_CanWalk = 0x2
        E_CanSwim = 0x4,
        E_Last
    }
    
    class MyAnimal
    {
       EAnimalCaps m_Caps;
    }

    class Frog
    {
        Frog() : 
            m_Caps(EAnimalCaps(E_CanWalk | E_CanSwim))
        {}
    }

    for (EAnimalCaps= E_First; i < E_Last; i = EAnimalCaps(i << 1))
    {}

假设枚举是按顺序编号是容易出错的。此外,您可能只希望迭代选定的枚举数。如果这个子集很小,显式遍历它可能是一个优雅的选择:

enum Item { Man, Wolf, Goat, Cabbage }; // or enum class

for (auto item : {Wolf, Goat, Cabbage}) { // or Item::Wolf, ...
    // ...
}

在评论中已经有关于std::initializer_list (c++ 11)的讨论。 我提到example是为了遍历枚举。

或者std::initializer_list和一个更简单的语法:

enum E {
    E1 = 4,
    E2 = 8,
    // ..
    En
};

constexpr std::initializer_list<E> all_E = {E1, E2, /*..*/ En};

然后

for (auto e : all_E) {
    // Do job with e
}

参考链接

大多数解决方案基于(MIN, MAX)范围内的循环,但忽略了枚举中可能存在漏洞的事实。

我的建议是:

        for (int i = MYTYPE_MIN; i <= MYTYPE_MAX; i++) {
            if (MYTYPE_IsValid(i)) {
                MYTYPE value = (MYTYPE)i;
                // DoStuff(value)
            }   
        }   
        

枚举就不行。也许枚举不是最适合您的情况。

一个常见的约定是将最后一个枚举值命名为MAX,并使用它来控制一个int类型的循环。