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

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


当前回答

使用lambda,我发现这是遍历枚举的最佳(现代)方式。 这大大提高了抽象性。 甚至可以使它成为模板,所以它适用于任何枚举。 这段代码不会给您带来clang(-tidy)问题。

#include <functional>

/// @brief Loop over all enum values where the last enum value is the invalid one
void forEachAction(std::function<void(Enum)> &&doThis) {
    for (int value = 0; value = static_cast<int>(Enum::LastValue); ++value ) {
        doThis(static_cast<Enum>(value ));
    }
}

...

forEachAction([this](Enum value) {
    ...  // what you want to execute for every enum
});

其他回答

如果你知道枚举值是连续的,例如Qt:Key枚举,你可以:

Qt::Key shortcut_key = Qt::Key_0;
for (int idx = 0; etc...) {
    ....
    if (shortcut_key <= Qt::Key_9) {
        fileMenu->addAction("abc", this, SLOT(onNewTab()),
                            QKeySequence(Qt::CTRL + shortcut_key));
        shortcut_key = (Qt::Key) (shortcut_key + 1);
    }
}

它像预期的那样工作。

还可以重载枚举类型的自增/自减操作符。

只需创建一个int型数组并遍历该数组,但使最后一个元素为-1并使用它作为退出条件。

enum为:

enum MyEnumType{Hay=12,Grass=42,Beer=39};

然后创建数组:

int Array[] = {Hay,Grass,Beer,-1};

for (int h = 0; Array[h] != -1; h++){
  doStuff( (MyEnumType) Array[h] );
}

当然,只要-1检查不与任何一个元素冲突,无论表示中的整数都不会被分解。

优点:枚举可以有你喜欢的任意顺序的任何值,并且仍然很容易迭代它们。 名称和值只定义一次,在第一个#define中。

缺点:如果你在工作中使用这个短语,你需要用一整段话来向你的同事解释。而且,必须声明内存来给你的循环提供迭代的东西是很烦人的,但我不知道有什么解决办法不限制你使用相邻值的枚举(如果枚举总是有相邻值,enum可能不会给你买那么多)。

//create a, b, c, d as 0, 5, 6, 7
#define LIST x(a) x(b,=5) x(c) x(d)
#define x(n, ...) n __VA_ARGS__,
enum MyEnum {LIST}; //define the enum
#undef x //needed
#define x(n,...) n ,
MyEnum myWalkableEnum[] {LIST}; //define an iterable list of enum values
#undef x //neatness

int main()
{
  std::cout << d;
  for (auto z : myWalkableEnum)
    std::cout << z;
}
//outputs 70567

使用未定义的宏包装器声明一个列表,然后在各种情况下以不同的方式定义包装器的技巧,除了这个应用程序之外,还有许多应用程序。

如果枚举以0开头,且增量始终为1。

enum enumType 
{ 
    A = 0,
    B,
    C,
    enumTypeEnd
};

for(int i=0; i<enumTypeEnd; i++)
{
   enumType eCurrent = (enumType) i;            
}

如果没有,我想唯一的原因是创造一个像

vector<enumType> vEnums;

添加条目,并使用普通的迭代器....