(怎么样)我可以计算枚举中的项目吗?

fue*_*zig 91 c++ enumeration count

当我有类似的东西时,我想到了这个问题

enum Folders {FA, FB, FC};
Run Code Online (Sandbox Code Playgroud)

并希望为每个文件夹创建一个容器数组:

ContainerClass*m_containers[3];
....
m_containers[FA] = ...; // etc.
Run Code Online (Sandbox Code Playgroud)

(使用的地图是更优雅的使用方法:std::map<Folders, ContainerClass*> m_containers;)

但回到我原来的问题:如果我不想对数组大小进行硬编码,有什么方法可以找出文件夹中有多少项?(不依赖于例如FC列表中的最后一项,ContainerClass*m_containers[FC+1]如果我没有弄错的话就会允许这样的事情.)

wic*_*ich 116

这并不是一个很好的方法,通常你会在枚举中看到一个额外的项目,即

enum foobar {foo, bar, baz, quz, FOOBAR_NR_ITEMS};
Run Code Online (Sandbox Code Playgroud)

那么你可以这样做:

int fuz[FOOBAR_NR_ITEMS];
Run Code Online (Sandbox Code Playgroud)

虽然还不是很好.

但是当然你会意识到只有enum中的项目数量是不安全的,例如

enum foobar {foo, bar = 5, baz, quz = 20};
Run Code Online (Sandbox Code Playgroud)

项目数量为4,但枚举值的整数值将超出数组索引范围.使用枚举值进行数组索引并不安全,您应该考虑其他选项.

编辑:根据要求,使特殊条目更加突出.

  • 称之为最后或总是_AT_END或其他不那么神秘的东西.把它__stick out__.因此,后续维护者在结束标记后不会意外添加新条目. (27认同)
  • 无论好坏,这是我们在组织中采用的方法.我们通常称它为FINAL_enumname_ENTRY,例如FINAL_foobar_ENTRY.我也看到人们在枚举声明之后使用一个单独的静态const FOOBAR_COUNT变量,这种方法稍微容易出错. (3认同)

Jos*_*ley 32

对于C++,有各种类型安全的枚举技术可用,其中一些(例如建议但从未提交过的Boost.Enum)包括对获取枚举大小的支持.

在C和C++中最简单的方法是采用为每个枚举类型声明... MAX值的约定:

enum Folders { FA, FB, FC, Folders_MAX = FC };
ContainerClass *m_containers[Folders_MAX + 1];
....
m_containers[FA] = ...; // etc.
Run Code Online (Sandbox Code Playgroud)

编辑:关于{ FA, FB, FC, Folders_MAX = FC}{FA, FB, FC, Folders_MAX]:我喜欢... MAX值设置为枚举几个原因的最后一个合法值:

  1. 常量的名称在技术上更准确(因为Folders_MAX给出了最大可能的枚举值).
  2. 就个人而言,我觉得Folders_MAX = FC从其他条目中脱颖而出(使得在不更新最大值的情况下意外添加枚举值有点困难,这是Martin York引用的问题).
  3. GCC包含有用的警告,例如"未包含在交换机中的枚举值"等代码,如下所示.让Folders_MAX == FC + 1打破这些警告,因为你最终会得到一堆...... MAX枚举值,这些值永远不应该包含在switch中.
switch (folder) 
{
  case FA: ...;
  case FB: ...;
  // Oops, forgot FC!
}

  • 为什么不这样做:`enum文件夹{FA,FB,FC,Folders_MAX}; ContainerClass*m_containers [Folders_MAX];`? (3认同)
  • 实际上,我觉得那些“有用”的警告是一种正确的痛苦。我喜欢在我开发时总是设置 -Wall -pedantic 等的好的警告,但这些警告只是愚蠢的。只有几个更糟糕的,比如为 &amp;&amp; || 建议括号 和 &amp; ^ | 运算符优先级。我的意思是,我认为 Java 是保姆语言,C 和 C++ 到底发生了什么...... (2认同)
  • 使用 Folders_max=FC 的缺点是每次向枚举添加内容时都必须更改它! (2认同)
  • 枚举文件夹{FA,FB,FC,Folders_MIN = FA,Folders_MAX = FC}; 只是为了强调它对迭代有用吗? (2认同)

Woj*_*gda 7

STL时尚的特质怎么样?例如:

enum Foo
{
    Bar,
    Baz
};
Run Code Online (Sandbox Code Playgroud)

写一个

std::numeric_limits<enum Foo>::max()
Run Code Online (Sandbox Code Playgroud)

专业化(如果你使用c ++ 11,可能是constexpr).然后,在您的测试代码中提供任何静态断言来维护std :: numeric_limits :: max()= last_item的约束.

  • 不幸的是,根据[这个答案](http://stackoverflow.com/a/9201960/2016221),这不会起作用. (2认同)
  • `std :: numeric_limits <enum Foo> :: max()`总是返回零...(参见链接答案的问题)在普通枚举上测试(`enum Foo {...}`),类型提示的枚举(`enum class Foo:uint8_t {...}`)与gcc 5.2.0 @ Linux和MinGW 4.9.3 @ Windows. (2认同)
  • -1; 如果你改变了答案,请告诉我,所以我可以撤消downvote.这个答案是一个不好的惯例.它是对"numeric_limits <T> :: max()"概念的误用.功能可以合理返回的唯一功能是枚举值最高.它将返回"2",但OP(在这种特定情况下)将需要它返回"3".一旦你有枚举的非默认值(`FB = 2057`),所有的赌注都会关闭,甚至不能'+ 1'来破解一分一秒的错误.如果有一个`numeric_limits <T> :: number_of_elements_of_the_set()`(或一个较短的名字),可以毫无歧义地使用它. (2认同)