我有一些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,但它看起来很难看,我从未见过有人在代码中这样做。是否有任何众所周知的范例来迭代枚举,或者我只需要修复枚举值的顺序? (让我们假装,我真的有一些改变枚举值顺序的绝佳理由)......
答案 0 :(得分:13)
您可以为operator++()
定义enum
。这具有以下优点:它使用标准增量运算符的众所周知的范例。 :)
根据您的枚举是否连续,您可以将其视为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--()
。
答案 1 :(得分:4)
不,没有办法这样做,因为无法保证有人没有编写如下代码:
enum Some
{
Some_Alpha = 0,
Some_Beta,
Some_Gamma = 42,
Some_Delta,
Some_Total
};
答案 2 :(得分:3)
您可以使用article查看此source code,了解如何使用静态类成员实现此功能。
答案 3 :(得分:1)
在C ++ 11中(可能更早),您可以使用以下hack来使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;
}
(这个答案是从here无耻地改编而来的。)
答案 4 :(得分:0)
enum Some
{
Some_first_ = 0,
Some_Alpha = Some_first_,
....
Some_last_
};
这样做可以先授予&amp;最后从不改变订单
答案 5 :(得分:0)
如果您不使用任何分配,则保证枚举以0开头顺序排列。 thers。
您可以做的最好的事情是在枚举定义中按顺序保留它们,并使用for循环遍历它们。
答案 6 :(得分:0)
我将所有枚举放在他们自己的命名空间中。例如:
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;
这显然是错误的。