C++ 删除枚举元素的重复

C++ 删除枚举元素的重复,c++,enums,enumeration,C++,Enums,Enumeration,我有以下枚举器,它可能会在程序开发过程中扩展: enum myEnum { Element1, Element2, Element3 ... ElementX Last }; 我有一个函数,它以以下方式使用枚举器: bool CheckEnumValidity(myEnum a) { bool valid = false; switch (a) { case Element1: case Element2:

我有以下枚举器,它可能会在程序开发过程中扩展:

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) 如果
CheckEnumValidity()
具有
myEnum
类型的参数,我是否应该在前面提到的
switch
语句中具有引发异常(或返回
false
)的
default
行为

注意事项:


C++11对我的应用程序不可用。

如果枚举确实不包含任何显式值赋值,则可以编写:

if (a <= Last) {
    return (a < Last);
} else {
    throw AnyExceptionYouWant();
}

if(a可能会更容易,通过编码指导原则、同行压力、策略执行(解雇任何不遵守编码指导原则的编程人员)或其他方式,确保使用
enum
的调用代码只提供命名值

换句话说,不允许将整数值转换为枚举类型。毕竟,这样做首先否定了使用枚举类型的大部分理由

尽管有这个建议,如果您想要测试,我会编写一个小程序,解析您的头文件,查找所有
enum
类型,并自动生成
SomeFunction()
。使用makefiles,可以轻松确保在相关头文件更改时运行程序,这意味着该函数将被更新、重新编译并链接到程序中,以保持检查与类型定义一致


至于您的检查函数是否应该抛出异常,这可以归结为值未通过测试的后果。如果您的程序确实不应该继续,则抛出异常。如果错误是良性的,并且您的程序可以以某种方式继续,只需记录一条错误消息(例如,to
std::cerr
)继续回答.< /p> < p>回答你的第一个问题,在C++中没有很简单的方法来做这件事,尽管我会在你的问题中留下一些注释,指向一些方法。 对于你的第二个问题,我建议你使用
默认值
案例。原因如下。第一个原因较弱,但后两个原因更强

  • 有些人可能会在不检查整数是否有效的情况下将其显式转换为枚举值。这应该被禁止,但有时仍然会发生,如果在代码检查中遗漏了此编程错误,您应该在运行时捕获它
  • 您可能从不受信任的外部源读取
    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;
        }
    }
    
    至于在默认情况下应该做什么,这取决于您的项目和特定的枚举。例如,如果在进入程序的大容量之前总是要验证枚举,这样可以防止无效值,如果违反了这一点就可以失败,那么您可能应该在pr之后抛出异常,甚至调用
    exit
    输入适当的错误消息–这是在运行时捕获的编程失败

    如果像这样失败不是一个选项,您可能至少应该尝试记录它,至少在调试版本中,这样您就可以检测到问题


    如果某个特定枚举的值无效,则根据它为什么有意义处理它,根据<为什么它有意义。< /P>使用<代码> Enm类MyNUM< /Calp>或命名空间。C++ 11不适用于我的应用程序。我给您留下了一个答案“2”,但是对于1,请尝试查看这个(免责声明:无耻插头)。:。这提供了一个

    是有效的
    方法,消除了对
    最后一个
    的需要,还提供了像
    枚举类
    这样的范围和大小的枚举,即使您没有使用C++11。您基本上需要某种宏来避免重复,这将尝试捕获一些最有用的方法。还有关于堆栈溢出的WER,其中显示了各种宏方法。您可能还希望搜索将枚举转换为字符串的方法,因为该方法的解决方案通常可以用于有效性检查。我进行了一些搜索,但在5分钟内找不到一个好的有效性问题。不过,请查看此枚举转换为字符串的问题,了解一些宏的想法s:。最容易实现的可能是使用X宏来生成枚举和开关。dlask,谢谢你的回答!你能进一步澄清我的第二个问题吗?如果我得到了一些显式的值赋值,该怎么办?除了最后一个之外,还有什么机制可以从
    enum
    中获取所有元素吗?@Konstantin异常对于指示意外值。