c++ 有没有什么众所周知的迭代枚举值的范例?

iibxawm4  于 2023-05-02  发布在  其他
关注(0)|答案(7)|浏览(213)

我有一些C++代码,其中声明了以下枚举:

enum Some 
{
   Some_Alpha = 0,
   Some_Beta,
   Some_Gamma,
   Some_Total
};
int array[Some_Total];

Alpha、Beta和Gamma的值是连续的,我很乐意使用以下循环来迭代它们:

for ( int someNo = (int)Some_Alpha; someNo < (int)Some_Total; ++someNo ) {}

这个循环是可以的,直到我决定改变枚举中声明的顺序,比如,将Beta作为第一个值,Alpha作为第二个值。这使循环头无效,因为现在我必须从Beta迭代到Total。那么,迭代枚举的最佳实践是什么呢?我想遍历所有的值,而不需要每次都改变循环头。我能想到一个解决方案:

enum Some 
{
   Some_Start = -1,
   Some_Alpha,
   ...
   Some_Total
};
int array[Some_Total];

并从(Start + 1)迭代到Total,但它看起来很丑,我从未见过有人在代码中这样做。是否有任何众所周知的范例来迭代枚举,或者我只需要修改枚举值的顺序?(假设我真的有一些很棒的理由来改变枚举值的顺序)。..

rur96b6h

rur96b6h1#

您可以为enum定义一个operator++()。这样做的优点是使用了众所周知的标准递增运算符范例。:)
根据你的枚举是否是连续的,你可以将它们视为int或使用开关:

Some& operator++(Some& obj)
{
# if YOUR_ENUMS_ARE_CONTIGUOUS
  int i = obj;
  if( ++i > Some_Total ) i = Some_Alpha;
  return obj = static_cast<Some>(i);
# else 
  switch(obj)
  {
    case Some_Alpha : obj = Some_Beta;  break;
    case Some_Beta  : obj = Some_Gamma; break;
    case Some_Gamma : obj = Some_Total; break;
    case Some_Total : obj = Some_Alpha; break;
    default: assert(false); // changed enum but forgot to change operator
  }
  return obj;
# endif
}

请注意,如果定义了operator++(),用户可能也会期望operator--()

w6lpcovy

w6lpcovy2#

不,没有办法做到这一点,因为不能保证有人没有写过类似的代码:

enum Some 
{
   Some_Alpha = 0,
   Some_Beta,
   Some_Gamma = 42,
   Some_Delta, 
  Some_Total
};
56lgkhnf

56lgkhnf3#

可以使用静态类成员。
示例中的article及其source code

elcex8rz

elcex8rz4#

在C++11(可能更早)中,你可以使用下面的技巧,使Some可迭代:

Some operator++(Some& s) {
    return s = (Some )(std::underlying_type<Some>::type(x) + 1); 
}
Some operator*(Some s) {
    return s;
} 
Some begin(Some s) {
    return Some_Alpha;

Some end(Some s) {
    return Some_Gamma;
}

int main() { 
    // the parenthesis here instantiate the enum
    for(const auto& s : Some()) { 
        // etc. etc.
    }
    return 0;
}

(This答案是无耻地改编自here。)

sh7euo9m

sh7euo9m5#

enum Some
{
   Some_first_ = 0,
   Some_Alpha = Some_first_,
....
   Some_last_
};

这样做你可以授予第一和最后永远不会改变秩序

dphi5xsq

dphi5xsq6#

如果不使用任何赋值,则枚举将保证是顺序的,从0开始作为第一个。其他人
你能做的最好的事情就是在枚举定义中按照你想要的顺序保存它们,然后用for循环遍历它们。

o75abkj4

o75abkj47#

我将所有Enum放在它们自己的命名空间中。示例:

namespace Foo {
enum Enum {
    First=0, // must be sequential
    Second,
    Third,
    End // must be last
};
}

在代码中:

for (int i=Foo::First; i!=Foo::End; i++) {
// do stuff
}

这是因为C++允许这样的东西(没有在编译器中测试):

enum Foo {
Alpha = 1
};

enum Bar {
Beta = 2
};

Foo foo = Beta;

这显然是错误的。

相关问题