当我有类似
之类的东西时,我想到了这个问题enum Folders {FA, FB, FC};
并希望为每个文件夹创建一个容器数组:
ContainerClass*m_containers[3];
....
m_containers[FA] = ...; // etc.
(使用地图使用起来更加优雅:std::map<Folders, ContainerClass*> m_containers;
)
但回到我原来的问题:如果我不想对数组大小进行硬编码,有什么方法可以找出文件夹中有多少项? (不依赖于例如FC
是列表中的最后一项,如果我没有弄错的话会允许ContainerClass*m_containers[FC+1]
之类的内容。)
答案 0 :(得分:109)
没有一个好方法可以做到这一点,通常你会在枚举中看到一个额外的项目,即
enum foobar {foo, bar, baz, quz, FOOBAR_NR_ITEMS};
那么你可以这样做:
int fuz[FOOBAR_NR_ITEMS];
虽然还不是很好。
但是当然你会意识到只有枚举中的项目数量是不安全的,例如。
enum foobar {foo, bar = 5, baz, quz = 20};
项目数为4,但枚举值的整数值将超出数组索引范围。使用枚举值进行数组索引并不安全,您应该考虑其他选项。
编辑:根据要求,使特殊条目更加突出。
答案 1 :(得分:31)
对于C ++,有各种type-safe enum techniques可用,其中一些(例如提议但未提交的Boost.Enum)包括对获取枚举大小的支持。
最简单的方法是在C语言和C ++中运行,它采用一种约定,为每个枚举类型声明一个MAX值:
enum Folders { FA, FB, FC, Folders_MAX = FC };
ContainerClass *m_containers[Folders_MAX + 1];
....
m_containers[FA] = ...; // etc.
修改:关于{ FA, FB, FC, Folders_MAX = FC}
与{FA, FB, FC, Folders_MAX]
:我更喜欢将... MAX值设置为枚举的最后一个合法值,原因如下:
Folders_MAX
给出了最大可能的枚举值)。Folders_MAX = FC
在其他条目中更突出(更难以在不更新最大值的情况下意外添加枚举值,这是Martin York引用的问题)。switch (folder) { case FA: ...; case FB: ...; // Oops, forgot FC! }
答案 2 :(得分:7)
STL时尚的特质怎么样?例如:
enum Foo
{
Bar,
Baz
};
写一个
std::numeric_limits<enum Foo>::max()
专业化(如果你使用c ++ 11,可能是constexpr)。然后,在您的测试代码中提供任何静态断言来维护std :: numeric_limits :: max()= last_item的约束。
答案 3 :(得分:3)
在枚举结尾处添加一个名为Folders_MAX或类似名称的条目,并在初始化数组时使用此值。
ContainerClass* m_containers[Folders_MAX];
答案 4 :(得分:2)
我喜欢使用枚举作为我的函数的参数。这是提供固定的&#34;选项&#34;的简单方法。这里最高投票答案的问题在于,使用它,客户可以指定一个&#34;无效选项&#34;。作为一个分拆,我建议基本上做同样的事情,但在枚举之外使用一个常量int来定义它们的数量。
enum foobar { foo, bar, baz, quz };
const int FOOBAR_NR_ITEMS=4;
这并不令人愉快,但如果你不更新枚举而不更新常量,它就是一个干净的解决方案。
答案 5 :(得分:1)
我真的没有办法真正了解C ++中枚举中的值的数量。如果您定义的值可能会导致您创建数组太大或太小的情况,那么前面提到的任何解决方案都可以工作,只要您没有定义枚举的值
enum example{ test1 = -2, test2 = -1, test3 = 0, test4 = 1, test5 = 2 }
在这个例子中,当你需要一个包含5个项目的数组时,结果将创建一个包含3个项目的数组
enum example2{ test1 , test2 , test3 , test4 , test5 = 301 }
在这个示例中,当您需要5个项目的数组时,结果将创建301个项目的数组
在一般情况下解决此问题的最佳方法是迭代您的枚举,但据我所知,这不在标准中
答案 6 :(得分:0)
这是在编译时执行此操作的最佳方法。我使用了 here 中的 arg_var count 答案。
#define PP_NARG(...) \
PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
#define PP_NARG_(...) \
PP_ARG_N(__VA_ARGS__)
#define PP_ARG_N( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63,N,...) N
#define PP_RSEQ_N() \
63,62,61,60, \
59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40, \
39,38,37,36,35,34,33,32,31,30, \
29,28,27,26,25,24,23,22,21,20, \
19,18,17,16,15,14,13,12,11,10, \
9,8,7,6,5,4,3,2,1,0
#define TypedEnum(Name, ...) \
struct Name { \
enum { \
__VA_ARGS__ \
}; \
static const uint32_t Name##_MAX = PP_NARG(__VA_ARGS__); \
}
#define Enum(Name, ...) TypedEnum(Name, __VA_ARGS__)
声明一个枚举:
Enum(TestEnum,
Enum_1= 0,
Enum_2= 1,
Enum_3= 2,
Enum_4= 4,
Enum_5= 8,
Enum_6= 16,
Enum_7= 32);
最大值将在此处提供:
int array [TestEnum::TestEnum_MAX];
for(uint32_t fIdx = 0; fIdx < TestEnum::TestEnum_MAX; fIdx++)
{
array [fIdx] = 0;
}