C++ (如何)我可以计算枚举中的项目吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2102582/
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
(How) can I count the items in an enum?
提问by fuenfundachtzig
This question came to my mind, when I had something like
这个问题出现在我的脑海中,当我有类似的事情时
enum Folders {FA, FB, FC};
and wanted to create an array of containers for each folder:
并想为每个文件夹创建一个容器数组:
ContainerClass*m_containers[3];
....
m_containers[FA] = ...; // etc.
(Using maps it's much more elegant to use: std::map<Folders, ContainerClass*> m_containers;
)
(使用地图这是更优雅的使用方法:std::map<Folders, ContainerClass*> m_containers;
)
But to come back to my original question: What if I do not want to hard-code the array size, is there a way to figure out how many items are in Folders? (Without relying on e.g. FC
being the last item in the list which would allow something like ContainerClass*m_containers[FC+1]
if I'm not mistaken.)
但是回到我最初的问题:如果我不想对数组大小进行硬编码怎么办,有没有办法计算出文件夹中有多少项目?(不依赖于例如FC
作为列表中的最后一项,ContainerClass*m_containers[FC+1]
如果我没记错的话,这将允许类似的事情。)
回答by wich
There's not really a good way to do this, usually you see an extra item in the enum, i.e.
没有什么好的方法可以做到这一点,通常你会在枚举中看到一个额外的项目,即
enum foobar {foo, bar, baz, quz, FOOBAR_NR_ITEMS};
So then you can do:
那么你可以这样做:
int fuz[FOOBAR_NR_ITEMS];
Still not very nice though.
不过还是不太好。
But of course you do realize that just the number of items in an enum is not safe, given e.g.
但是当然您确实意识到仅枚举中的项目数量是不安全的,例如
enum foobar {foo, bar = 5, baz, quz = 20};
the number of items would be 4, but the integer values of the enum values would be way out of the array index range. Using enum values for array indexing is not safe, you should consider other options.
项目数为 4,但枚举值的整数值将超出数组索引范围。使用枚举值进行数组索引并不安全,您应该考虑其他选项。
edit: as requested, made the special entry stick out more.
编辑:根据要求,使特殊条目更加突出。
回答by Josh Kelley
For C++, there are various type-safe enum techniquesavailable, and some of those (such as the proposed-but-never-submitted Boost.Enum) include support for getting the size of a enum.
对于 C++,有各种类型安全的枚举技术可用,其中一些(例如提议但从未提交的Boost.Enum)包括对获取枚举大小的支持。
The simplest approach, which works in C as well as C++, is to adopt a convention of declaring a ...MAX value for each of your enum types:
在 C 和 C++ 中都适用的最简单的方法是采用为每个枚举类型声明 ...MAX 值的约定:
enum Folders { FA, FB, FC, Folders_MAX = FC };
ContainerClass *m_containers[Folders_MAX + 1];
....
m_containers[FA] = ...; // etc.
Edit: Regarding { FA, FB, FC, Folders_MAX = FC}
versus {FA, FB, FC, Folders_MAX]
: I prefer setting the ...MAX value to the last legal value of the enum for a few reasons:
编辑:关于{ FA, FB, FC, Folders_MAX = FC}
与{FA, FB, FC, Folders_MAX]
:我更喜欢将 ...MAX 值设置为枚举的最后一个合法值,原因如下:
- The constant's name is technically more accurate (since
Folders_MAX
gives the maximum possible enum value). - Personally, I feel like
Folders_MAX = FC
stands out from other entries out a bit more (making it a bit harder to accidentally add enum values without updating the max value, a problem Martin York referenced). - GCC includes helpful warnings like "enumeration value not included in switch" for code such as the following. Letting Folders_MAX == FC + 1 breaks those warnings, since you end up with a bunch of ...MAX enumeration values that should never be included in switch.
- 常量的名称在技术上更准确(因为
Folders_MAX
给出了最大可能的枚举值)。 - 就个人而言,我觉得
Folders_MAX = FC
从其他条目中脱颖而出更多(使得在不更新最大值的情况下意外添加枚举值变得更加困难,Martin York 引用了一个问题)。 - GCC 包含有用的警告,例如“开关中不包含枚举值”,用于如下代码。Letting Folders_MAX == FC + 1 打破了这些警告,因为你最终会得到一堆 ...MAX 枚举值,这些值永远不应该包含在 switch 中。
switch (folder) { case FA: ...; case FB: ...; // Oops, forgot FC! }
回答by Wojciech Migda
How about traits, in an STL fashion? For instance:
以 STL 的方式来说,traits 怎么样?例如:
enum Foo
{
Bar,
Baz
};
write an
写一个
std::numeric_limits<enum Foo>::max()
specialization (possibly constexpr if you use c++11). Then, in your test code provide any static assertions to maintain the constraints that std::numeric_limits::max() = last_item.
专业化(如果您使用 c++11,可能是 constexpr)。然后,在您的测试代码中提供任何静态断言来维护 std::numeric_limits::max() = last_item 的约束。
回答by Kevin Doyon
Add a entry, at the end of your enum, called Folders_MAX or something similar and use this value when initializing your arrays.
在枚举末尾添加一个名为 Folders_MAX 或类似名称的条目,并在初始化数组时使用此值。
ContainerClass* m_containers[Folders_MAX];
回答by BuvinJ
I like to use enums as arguments to my functions. It's an easy means to provide a fixed list of "options". The trouble with the top voted answer here is that using that, a client can specify an "invalid option". As a spin off, I recommend doing essentially the same thing, but use a constant int outside of the enum to define the count of them.
我喜欢使用枚举作为函数的参数。这是提供固定“选项”列表的一种简单方法。此处投票最高的答案的问题在于,使用它,客户端可以指定“无效选项”。作为分拆,我建议做本质上相同的事情,但在枚举之外使用常量 int 来定义它们的计数。
enum foobar { foo, bar, baz, quz };
const int FOOBAR_NR_ITEMS=4;
It's not pleasant, but it's a clean solution if you don't change the enum without updating the constant.
这并不令人愉快,但如果您在不更新常量的情况下不更改枚举,这是一个干净的解决方案。
回答by BuvinJ
I really do not see any way to really get to the number of values in an enumeration in C++. Any of the before mention solution work as long as you do not define the value of your enumerations if you define you value that you might run into situations where you either create arrays too big or too small
我真的没有看到任何方法可以真正获得 C++ 枚举中的值数量。前面提到的任何解决方案只要您不定义枚举的值就可以工作,如果您定义了可能会遇到创建数组太大或太小的情况的值
enum example{ test1 = -2, test2 = -1, test3 = 0, test4 = 1, test5 = 2 }
in this about examples the result would create a array of 3 items when you need an array of 5 items
在这个关于示例中,当您需要一个包含 5 个项目的数组时,结果将创建一个包含 3 个项目的数组
enum example2{ test1 , test2 , test3 , test4 , test5 = 301 }
in this about examples the result would create a array of 301 items when you need an array of 5 items
在这个 about 示例中,当您需要一个包含 5 个项目的数组时,结果将创建一个包含 301 个项目的数组
The best way to solve this problem in the general case would be to iterate through your enumerations but that is not in the standard yet as far as I know
在一般情况下解决此问题的最佳方法是遍历您的枚举,但据我所知,这不在标准中