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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3475152/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 12:54:15  来源:igfitidea点击:

Why can't I increment a variable of an enumerated type?

c++

提问by BeeBand

I have a enumerated type StackID, and I am using the enumeration to refer to an index of a particular vector and it makes my code easier to read.

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

However, I now have the need to create a variable called nextAvailof type StackID. (it actually refers to a particular stackID ). I tried to increment it but in C++, the following is illegal:

但是,我现在需要创建一个名为nextAvailtype的变量StackID。(它实际上是指特定的 stackID )。我试图增加它,但在 C++ 中,以下是非法的:

nextAvail++;

Which sort of makes sense to me ... because there's no bounds checking.

哪种对我来说有意义......因为没有边界检查。

I'm probably overlooking something obvious, but what's a good substitute?

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



I also want to link to thisquestion.

我也想链接到这个问题。

回答by sbi

I'm probably overlooking something obvious, but what's a good substitute?

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

Overloading operator++:

重载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;
}

回答by Igor Zevaka

Because enumerations do not have to be contiguous. E.g. take this example:

因为枚举不必是连续的。举个例子:

enum Colors {
 cRed, // = 0
 cBlue, // = 1
 cGreen = 3
}

What should happen in this scenario?

在这种情况下应该发生什么?

Colors color = cBlue;
Colors other = color++;

Should other be cGreenor should it be 2. In that case it's not a valid enumeration member anymore. What about this?

其他应该是cGreen还是应该是2。在这种情况下,它不再是有效的枚举成员。那这个呢?

Colors color = cGreen;
Colors other = color++;

Should otherbe cRed(wrap around) or 4?

应该othercRed(环绕)还是 4?

As you can see, being able to increment enumeration values introduces a whole lot of questions and complicates the simple mechanism that they intend to be.

如您所见,能够增加枚举值会带来很多问题,并使它们想要的简单机制变得复杂。

If all you care about is the integer value being incremented, then simply cast to intand increment that.

如果您只关心递增的整数值,那么只需将其转换为int并递增即可。

回答by unwind

Casting back and forth to/from intis of course the obvious solution, then you make clear that you understand that the addition is happening "outside" the enum:

来回转换int当然是显而易见的解决方案,然后您明确表示您了解添加是在“外部”发生的enum

nextAvail = static_cast<StackID>(static_cast<int>(nextAvail) + 1);

回答by Andreas Brinck

Why not store nextAvailas an intinstead if you're going to do arithmetic operations on it?

如果要对其进行算术运算,为什么不存储nextAvail为 anint呢?

Another option would be to wrap the enum in your own type and overload operator ++for it (which also could wrap around or something for instance).

另一种选择是将枚举包装在您自己的类型中并operator ++为其重载(例如也可以环绕或其他东西)。

回答by Manuel Schmitzberger

I've overloaded the ++/--operator in this way:

++/--以这种方式重载了运算符:

enum STATE {STATE_1, STATE_2, STATE_3, STATE_4, STATE_5, STATE_6};

// Overload the STATE++ operator

// 重载 STATE++ 运算符

inline STATE& operator++(STATE& state, int) {
    const int i = static_cast<int>(state)+1;
    state = static_cast<STATE>((i) % 6);
    return state;
}

// Overload the STATE-- operator

// 重载 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;
}

回答by PaulJWilliams

An enumeration is semantically supposed to represent a set of distinct related, values.

枚举在语义上应该表示一组不同的相关值。

So you could have

所以你可以有

enum Colour {RED, GREEN, BLUE};

But that should be equivalent to:

但这应该相当于:

enum Colour {GREEN, BLUE, RED};

The problem is that if you increment an enum then those representations are not the same. GREEN++ in the first case is not the same as GREEN++ in the second.

问题是,如果你增加一个枚举,那么这些表示就不一样了。第一种情况下的 GREEN++ 与第二种情况下的 GREEN++ 不同。

Making your program dependent on the declaration of the enum is a recipe for disaster - maintainers may assume that the order of the enum doesnt matter, introducing many silent bugs.

让你的程序依赖于枚举的声明是灾难的秘诀——维护者可能认为枚举的顺序无关紧要,从而引入了许多无声的错误。

回答by egrunin

Enums are going to be type int, so you can cast them. Is this what you're trying to do?

枚举将是 type int,因此您可以投射它们。这是你想要做的吗?

int ndx = (int) StackID.SomeValue;
...
++ndx;

This is going to make someone very confused down the line, of course.

当然,这会让某人非常困惑。

It occurs to me that you're using an enumwhere you should be using const, or even #define. enumis most appropriate when you have arbitraryvalues (where the exact value is not meaningful).

我突然想到您正在使用enum您应该使用的地方const,甚至#define. enum当您具有任意值(其中确切值没有意义)时最合适。

回答by Chubsdad

With respect to oprator++, $5.2.6/1 states- "The type of the operand shall be an arithmetic type or a pointer to a complete object type."

关于 oprator++,$5.2.6/1 声明-“操作数的类型应为算术类型或指向完整对象类型的指针。”

StackID does not fit the bill here. It is of enumeration type.

StackID 不符合这里的要求。它是枚举类型。

One option is like this

一种选择是这样的

$5.7/1 - "For addition, either both operands shall have arithmetic or enumeration type, or one operand shall be a pointer to a completely defined object type and the other shall have integral or enumeration type."

$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;
}