为什么我不能增加枚举类型的变量?

时间:2010-08-13 08:29:28

标签: c++

我有一个枚举类型StackID,我使用枚举来引用特定向量的索引,这使我的代码更容易阅读。

但是,我现在需要创建一个名为nextAvail的{​​{1}}类型的变量。 (它实际上指的是特定的stackID)。我尝试增加它,但在C ++中,以下是非法的:

StackID

哪种对我有意义......因为没有界限检查。

我可能忽略了一些明显的东西,但有什么好的替代品?


我还想链接到this问题。

10 个答案:

答案 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++;

othercRed(环绕)还是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);