我只是注意到不能在枚举上使用标准数学运算符,如++或+=。
那么,在c++枚举中遍历所有值的最佳方法是什么?
我只是注意到不能在枚举上使用标准数学运算符,如++或+=。
那么,在c++枚举中遍历所有值的最佳方法是什么?
当前回答
将变量强制转换为int&类型可以在保持类型可读的同时进行递增。
#include <iostream>
enum MyEnum
{
ONE,
TWO,
THREE,
FOUR,
};
int main()
{
for (MyEnum v = MyEnum::ONE; v <= MyEnum::FOUR; ++(int&)v)
{
std::cout<<v<<std::endl;
}
return 0;
}
0
1
2
3
其他回答
(把Marski的回答当作一个很大的暗示……)
由于枚举定义的主体与初始化列表相同,如果我们使用一个简单的宏来写出值,就可以在不重复项目列表的情况下做到这一点:
#define ITEM_LIST_MACRO Wolf, Goat, Cabbage
enum Item { ITEM_LIST_MACRO }; // Define the enum
// Now iterate through it
for (auto item : { ITEM_LIST_MACRO }) {
}
优点:简单,没有重复,不需要保持恼人的第一个/最后一个哨兵值。(事实上,我认为这可能是目前为止建议的唯一解决方案,不需要用户记得在新项目添加到列表时更新“结束”标记。)
缺点:不适用于范围限定的枚举(enum类),因为初始化列表需要范围(Item::Wolf等)。如果你想指定枚举成员的值而不是默认值,同样不起作用。
对于MS编译器:
#define inc_enum(i) ((decltype(i)) ((int)i + 1))
enum enumtype { one, two, three, count};
for(enumtype i = one; i < count; i = inc_enum(i))
{
dostuff(i);
}
注意:这比简单的模板化自定义迭代器答案要少得多。
你可以通过使用typeof而不是decltype来让它与GCC一起工作,但我现在没有那个编译器来确保它能编译。
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]
}
在Bjarne Stroustrup的c++编程语言书中,你可以读到他建议为特定的枚举重载操作符++。枚举是用户定义的类型,语言中存在针对这些特定情况的重载运算符。
你将能够编写以下代码:
#include <iostream>
enum class Colors{red, green, blue};
Colors& operator++(Colors &c, int)
{
switch(c)
{
case Colors::red:
return c=Colors::green;
case Colors::green:
return c=Colors::blue;
case Colors::blue:
return c=Colors::red; // managing overflow
default:
throw std::exception(); // or do anything else to manage the error...
}
}
int main()
{
Colors c = Colors::red;
// casting in int just for convenience of output.
std::cout << (int)c++ << std::endl;
std::cout << (int)c++ << std::endl;
std::cout << (int)c++ << std::endl;
std::cout << (int)c++ << std::endl;
std::cout << (int)c++ << std::endl;
return 0;
}
测试代码:http://cpp.sh/357gb
注意,我使用的是枚举类。Code也可以很好地使用enum。但我更喜欢枚举类,因为它们是强类型的,可以防止我们在编译时犯错误。
枚举就不行。也许枚举不是最适合您的情况。
一个常见的约定是将最后一个枚举值命名为MAX,并使用它来控制一个int类型的循环。