我有一个枚举类型StackID
,我使用枚举来引用特定向量的索引,这使我的代码更容易阅读。
但是,我现在需要创建一个名为nextAvail
的{{1}}类型的变量。 (它实际上指的是特定的stackID)。我尝试增加它,但在C ++中,以下是非法的:
StackID
哪种对我有意义......因为没有界限检查。
我可能忽略了一些明显的东西,但有什么好的替代品?
我还想链接到this问题。
答案 0 :(得分:21)
我可能忽略了一些明显的东西,但有什么好的替代品?
重载operator++
:
// Beware, brain-compiled code ahead!
StackID& operator++(StackID& stackID)
{
#if MY_ENUMS_ARE_CONTIGUOUS && I_DO_NOT_WORRY_ABOUT_OVERFLOW
return stackID = static_cast<StackID>( ++static_cast<int>(stackID) );
#else
switch(stackID) {
case value1 : return stackID = value2;
case value2 : return stackID = value3;
...
case valueN : return stackID = value1;
}
assert(false);
return stackID; // some compilers might warn otherwise
#endif
}
StackID operator++(StackID& stackID, int)
{
StackID tmp(stackID);
++stackID;
return tmp;
}
答案 1 :(得分:15)
因为枚举不必是连续的。例如。举个例子:
enum Colors {
cRed, // = 0
cBlue, // = 1
cGreen = 3
}
在这种情况下会发生什么?
Colors color = cBlue;
Colors other = color++;
其他应该是cGreen
还是应该是2.在这种情况下,它不再是有效的枚举成员。那怎么样?
Colors color = cGreen;
Colors other = color++;
other
应cRed
(环绕)还是4?
正如您所看到的,能够增加枚举值会引入大量问题,并使他们想要的简单机制变得复杂。
如果您关心的是整数值递增,那么只需转换为int
并递增。
答案 2 :(得分:7)
来回int
来回传播当然是显而易见的解决方案,然后你明确表示你明白增加发生在“{1}}”之外:
enum
答案 3 :(得分:2)
如果您要对其进行算术运算,为什么不将nextAvail
存储为int
?
另一种选择是将枚举包装在你自己的类型中并为它重载operator ++
(例如也可以包裹或者某些东西)。
答案 4 :(得分:1)
在语义上,枚举应该表示一组不同的相关值。
所以你可以拥有
enum Colour {RED, GREEN, BLUE};
但那应该相当于:
enum Colour {GREEN, BLUE, RED};
问题是如果你增加枚举,那么那些表示就不一样了。第一种情况下的GREEN ++与第二种情况下的GREEN ++不同。
使你的程序依赖于enum的声明是灾难的一个方法 - 维护者可能会认为枚举的顺序无关紧要,引入了许多无声的错误。
答案 5 :(得分:1)
枚举将是int
类型,因此您可以投射它们。这是你想要做的吗?
int ndx = (int) StackID.SomeValue;
...
++ndx;
当然,这会让某些人感到非常困惑。
我发现您使用的enum
应该使用const
,甚至是#define
。如果您拥有任意值(其中确切的值没有意义),enum
最合适。
答案 6 :(得分:0)
关于oprator ++,$ 5.2.6 / 1状态 - “操作数的类型应为算术类型或指向完整对象类型的指针。”
StackID不适合这里的账单。它是枚举类型。
一个选项就是这个
$ 5.7 / 1 - “另外,两个操作数都应具有算术或枚举类型,或者一个操作数应是指向完全定义的对象类型的指针,另一个操作数应具有整数或枚举类型。”
enum Possibility {Yes, No, Maybe};
Possibility operator++(Possibility const& r){
return Possibility(r + 1); // convert r to integer, add 1, convert back to Enum
}
int main(){
Possibility p = Yes;
Possibility p1 = ++p;
}
答案 7 :(得分:0)
我以这种方式重载了++/--
运算符:
enum STATE {STATE_1, STATE_2, STATE_3, STATE_4, STATE_5, STATE_6};
//重载STATE ++运算符
inline STATE& operator++(STATE& state, int) {
const int i = static_cast<int>(state)+1;
state = static_cast<STATE>((i) % 6);
return state;
}
//重载STATE--运算符
inline STATE& operator--(STATE& type, int) {
const int i = static_cast<int>(type)-1;
if (i < 0) {
type = static_cast<STATE>(6);
} else {
type = static_cast<STATE>((i) % 6);
}
return type;
}
答案 8 :(得分:0)
我对使用C + C ++解决方案来实现for
循环递增枚举感到非常满意。
for (Dwg_Version_Type v = R_INVALID; v <= R_AFTER; v++)
=>
int vi;
for (Dwg_Version_Type v = R_INVALID;
v <= R_AFTER;
vi = (int)v, vi++, v = (Dwg_Version_Type)vi)
这里的其他解决方案不是C向后兼容,而且很大。
答案 9 :(得分:0)
非常简单:
nextAvail = (StackID)(nextAvail + 1);