C++ 使用枚举作为数组索引

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/404231/
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-27 15:09:56  来源:igfitidea点击:

Using an enum as an array index

c++enums

提问by Jeremy Ruten

I have this enum:

我有这个枚举:

enum ButtonState {
    BUTTON_NORMAL = 0,
    BUTTON_PRESSED = 1,
    BUTTON_CLICKED = 2
};

const u8 NUM_BUTTON_STATES = 3;

In my Button class I have member variables ButtonState state;and ButtonColors colors[NUM_BUTTON_STATES];. When drawing the button, I use colors[state]to get the colours for whatever state the button is in.

在我的 Button 类中,我有成员变量ButtonState state;ButtonColors colors[NUM_BUTTON_STATES];. 绘制按钮时,我使用colors[state]获取按钮处于任何状态的颜色。

My questions:

我的问题:

  1. Is this good programming style? Is there a better way to do it? (I usually only use enums with switch statements... using an enum as an array index doesn't feel right.)
  2. Do I haveto specify the values of the enum? It seems to start from 0 by default and increment by 1 but is it guaranteed to work that way in all compilers?
  1. 这是好的编程风格吗?有没有更好的方法来做到这一点?(我通常只使用带有 switch 语句的枚举......使用枚举作为数组索引感觉不对。)
  2. 是否必须指定枚举的值?它似乎默认从 0 开始并以 1 递增,但是否保证在所有编译器中都这样工作?

采纳答案by Mr.Ree

Is this good programming style?

这是好的编程风格吗?

I think so. I do the same thing quite frequently.

我想是这样。我经常做同样的事情。

Is there a better way to do it?

有没有更好的方法来做到这一点?

class Button
{
public:
    // Used for array indexes!  Don't change the numbers!
  enum State {
    NORMAL = 0,
    PRESSED,
    CLICKED,
    NUMBER_OF_BUTTON_STATES
  };
};

Drawback is that NUMBER_OF_BUTTON_STATESis now a valid Button::Statevalue. Not a big issue if you are passing these values around as ints. But trouble if you are actually expecting a Button::State.

缺点是NUMBER_OF_BUTTON_STATES现在是有效的Button::State值。如果您将这些值作为ints传递,这不是大问题。但是如果你真的期待一个Button::State ,那就麻烦了。

Using an enum as an array index doesn't feel right.

使用枚举作为数组索引感觉不对。

It's fine. Just DOCUMENTit, so the next guy knows what's going on! (That's what comments are for.)

没关系。只要文件,所以未来的家伙知道是怎么回事!(这就是评论的用途。)

Do I have to specify the values of the enum?

我是否必须指定枚举的值?

With no '=' assignment, enum's are supposed tostart at zero and increment upwards.

如果没有 '=' 赋值,枚举应该从零开始并向上递增。

If a enum entry has an '=' assigned value, subsequent non '=' enum entries continue counting from there.

如果枚举条目具有 '=' 分配值,则后续非 '=' 枚举条目从那里继续计数。

Source: The Annotated C++ Reference Manual, pg 113

来源:带 注释的 C++ 参考手册,第 113 页

That said, I like to specify the initial value just to make the code that much clearer.

也就是说,我喜欢指定初始值只是为了使代码更清晰。

回答by Johannes Schaub - litb

Yeah it will work well. That said, in any case, you reallyshould put another entry in your enumeration defining the value of the amount of items:

是的,它会运作良好。也就是说,无论如何,您确实应该在枚举中放置另一个条目来定义项目数量的值:

enum ButtonState {
    BUTTON_NORMAL,
    BUTTON_PRESSED,
    BUTTON_CLICKED,
    STATE_COUNT
};

Then you can define the array like

然后你可以像这样定义数组

Color colors[STATE_COUNT];

otherwise, it's a mess to keep the amount of states synchronous with the size of the array. Enumerations will always start with zero if not otherwise initialized, and then each additional entry will be assigned a value one above the previous one, if not otherwise initialized. Of course it also wouldn't hurt if you put a zero explicitly if you want. If you don't mind additional code, i would wrap the access to the raw array using a function like

否则,保持状态数量与数组大小同步是一团糟。如果未以其他方式初始化,枚举将始终从零开始,然后如果未以其他方式初始化,则每个附加条目将被分配一个比前一个条目高一的值。当然,如果你愿意的话,如果你明确地设置零也不会受到伤害。如果你不介意额外的代码,我会使用像这样的函数来包装对原始数组的访问

Color & operator[](ButtonState state) {
    return array[state];
}

Or an equivalent getColorfunction forwarding the request. That would forbid directly indexing the array with some integer, which would almost certainly at some point fail because one gets the indexes wrong.

getColor转发请求的等效功能。这将禁止用某个整数直接索引数组,这几乎肯定会在某些时候失败,因为索引错误。

回答by Stefan

Using an enum is ok. But you don't have to specify values for every item. It's enough to specify the first value. I wouldn't assume that enums start at 0, because I've used compilers which used 1 as the starting value (not for PCs but some compilers for microcontrollers have some weird behavior). Also, you could get rid of the const:

使用枚举是可以的。但是您不必为每个项目指定值。指定第一个值就足够了。我不会假设枚举从 0 开始,因为我使用了使用 1 作为起始值的编译器(不是用于 PC,而是用于微控制器的一些编译器有一些奇怪的行为)。此外,您可以摆脱 const:

enum ButtonState {
    BUTTON_NORMAL = 0,
    BUTTON_PRESSED,
    BUTTON_CLICKED,
    NUM_BUTTON_STATES
};

回答by Roddy

Style-wise, it's just fine.

风格方面,这很好。

Pascal-based languages like Delphi allow array bounds to be specified as an enum type, so you can only use items of that specific type as an index.

Delphi 等基于 Pascal 的语言允许将数组边界指定为枚举类型,因此您只能使用该特定类型的项作为索引。

回答by Roddy

Question 1: I think it's good programming style. I use it all the time. Question 2: As far as I know, it is guaranteed to work that way, so you don't have to specify the values.

问题1:我认为这是很好的编程风格。我用它所有的时间。问题 2:据我所知,它可以保证以这种方式工作,因此您不必指定值。

And I would put NUM_BUTTON_STATES into the enum as well.

我也会将 NUM_BUTTON_STATES 放入枚举中。

回答by Mark Ransom

It is perfectly normal to use an enum for indexing into an array.

使用枚举对数组进行索引是完全正常的。

You don't have to specify each enum value, they will increment automatically by 1. Letting the compiler pick the values reduces the possibility of mistyping and creating a bug, but it deprives you of seeing the values, which might be useful in debugging.

您不必指定每个枚举值,它们会自动递增 1。让编译器选择这些值可以减少错误输入和创建错误的可能性,但它会使您无法看到这些值,这在调试中可能很有用。

回答by WOPR

It's fine, but I'd want to do some bounds checking on the array, as if someone adds another ButtonState, you'll have a problem.

没关系,但我想对数组进行一些边界检查,就好像有人添加了另一个 ButtonState,你会遇到问题。

Also, the elements of the colors array are immutable, so maybe look at using a different collection to array so that you can enforce that immutability. Maybe a Dictionary<ButtonState,ButtonColor>

此外,colors 数组的元素是不可变的,所以也许可以考虑使用不同的集合来数组,以便您可以强制执行该不变性。也许一个Dictionary<ButtonState,ButtonColor>