我只是注意到不能在枚举上使用标准数学运算符,如++或+=。
那么,在c++枚举中遍历所有值的最佳方法是什么?
我只是注意到不能在枚举上使用标准数学运算符,如++或+=。
那么,在c++枚举中遍历所有值的最佳方法是什么?
当前回答
如果你知道枚举值是连续的,例如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);
}
}
它像预期的那样工作。
其他回答
如果枚举以0开头,且增量始终为1。
enum enumType
{
A = 0,
B,
C,
enumTypeEnd
};
for(int i=0; i<enumTypeEnd; i++)
{
enumType eCurrent = (enumType) i;
}
如果没有,我想唯一的原因是创造一个像
vector<enumType> vEnums;
添加条目,并使用普通的迭代器....
您可以尝试并定义以下宏:
#define for_range(_type, _param, _A1, _B1) for (bool _ok = true; _ok;)\
for (_type _start = _A1, _finish = _B1; _ok;)\
for (int _step = 2*(((int)_finish)>(int)_start)-1;_ok;)\
for (_type _param = _start; _ok ; \
(_param != _finish ? \
_param = static_cast<_type>(((int)_param)+_step) : _ok = false))
现在你可以使用它:
enum Count { zero, one, two, three };
for_range (Count, c, zero, three)
{
cout << "forward: " << c << endl;
}
它可以用来在无符号、整数、枚举和字符之间来回迭代:
for_range (unsigned, i, 10,0)
{
cout << "backwards i: " << i << endl;
}
for_range (char, c, 'z','a')
{
cout << c << endl;
}
尽管它的定义很尴尬,但它优化得很好。我看了一下vc++中的反汇编程序。 代码非常高效。不要推迟,但是三个for语句:编译器在优化后只会产生一个循环!你甚至可以定义封闭的循环:
unsigned p[4][5];
for_range (Count, i, zero,three)
for_range(unsigned int, j, 4, 0)
{
p[i][j] = static_cast<unsigned>(i)+j;
}
显然,不能在有间隙的枚举类型中进行迭代。
大多数解决方案基于(MIN, MAX)范围内的循环,但忽略了枚举中可能存在漏洞的事实。
我的建议是:
for (int i = MYTYPE_MIN; i <= MYTYPE_MAX; i++) {
if (MYTYPE_IsValid(i)) {
MYTYPE value = (MYTYPE)i;
// DoStuff(value)
}
}
我经常这样做
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))
{}
下面是另一种只适用于连续枚举的解决方案。它给出了期望的迭代,除了增量中的丑陋,这是它的归属,因为这是c++中破坏的地方。
enum Bar {
One = 1,
Two,
Three,
End_Bar // Marker for end of enum;
};
for (Bar foo = One; foo < End_Bar; foo = Bar(foo + 1))
{
// ...
}