我有以下枚举器,它可能会在程序开发过程中进行扩展:
enum myEnum {
Element1,
Element2,
Element3
...
ElementX
Last
};
我有一个以下列方式使用枚举器的函数:
bool CheckEnumValidity(myEnum a)
{
bool valid = false;
switch (a) {
case Element1:
case Element2:
case Element3:
case ...
case ElementX:
valid true;
break;
case Last:
valid false;
break;
};
return valid;
}
问题:
1)我在我的程序中的两个位置复制Element1
,Element2
等。如何以最安全的方式摆脱重复?
2)如果default
的参数为{{1},我是否应该在上述false
语句中引发异常(或返回switch
)的CheckEnumValidity()
行为输入?
备注:
C ++ 11对我的应用程序不可用。
答案 0 :(得分:2)
如果您的枚举确实不包含任何显式值赋值,那么您可以写:
if (a <= Last) {
return (a < Last);
} else {
throw AnyExceptionYouWant();
}
答案 1 :(得分:1)
通过编码指南,同行压力,政策执行(解雇任何不遵守编码指南的程序员)或其他方法来确保使用enum
仅使用的代码来提供服务可能会更容易命名值。
换句话说,不允许将整数值转换为枚举类型。毕竟,做这些事情否定了首先使用枚举类型的大部分原因。
如果,尽管有这个建议,你想测试,我会编写一个小程序来解析你的头文件,查找所有enum
类型,并自动生成你的SomeFunction()
。使用makefile,很容易确保只要相关的头文件发生变化就运行程序,这意味着该函数将被更新,重新编译并链接到您的程序中,以使检查与类型定义保持一致。
关于你的检查函数是否应抛出异常,这可归结为一个值未通过测试的结果。如果您的程序真的不能继续,那么抛出异常。如果错误是良性的并且您的程序可以以某种方式继续,只需记录错误消息(例如,std::cerr
)并继续。
答案 2 :(得分:1)
要回答你的第一个问题,在C ++中没有非常简单的方法可以做到这一点,不过我会在你的问题上留下一些评论,指出一些方法。
对于您的第二个问题,我建议您使用default
案例。这就是原因。第一个原因是较弱,但最后两个更强。
struct
或其他数据,其中struct
包含枚举字段,但忘记对其进行正确验证。不受信任的外部源甚至可以是使用旧版程序保存的文件,其中枚举具有不同的有效值集。即使是这样简单的事情:
enum A {X = 1, Y, Z};
int main()
{
A foo;
switch (foo) {
case X: return 0;
case Y: return 1;
case Z: return 2;
}
}
关于在默认情况下应该做什么,它取决于您的项目和特定的枚举。例如,如果在进入程序的大部分之前应始终验证枚举,从而防止无效值,并且如果违反则可以失败,那么您应该抛出异常甚至在打印后调用exit
一个合适的错误消息 - 这是在运行时捕获的编程失败。
如果这样的失败不是一个选项,你至少应该尝试记录它,至少在调试版本中,这样你就可以发现问题。
如果无效值对特定的枚举有意义,那么根据它为什么有意义,根据你认为适合的枚举处理它。