删除重复的枚举元素

时间:2015-06-12 11:08:13

标签: c++ enums enumeration

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

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)我在我的程序中的两个位置复制Element1Element2等。如何以最安全的方式摆脱重复?

2)如果default的参数为{{1},我是否应该在上述false语句中引发异常(或返回switch)的CheckEnumValidity()行为输入?

备注:

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

3 个答案:

答案 0 :(得分:2)

如果您的枚举确实不包含任何显式值赋值,那么您可以写:

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

答案 1 :(得分:1)

通过编码指南,同行压力,政策执行(解雇任何不遵守编码指南的程序员)或其他方法来确保使用enum仅使用的代码来提供服务可能会更容易命名值。

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

如果,尽管有这个建议,你想测试,我会编写一个小程序来解析你的头文件,查找所有enum类型,并自动生成你的SomeFunction()。使用makefile,很容易确保只要相关的头文件发生变化就运行程序,这意味着该函数将被更新,重新编译并链接到您的程序中,以使检查与类型定义保持一致。

关于你的检查函数是否应抛出异常,这可归结为一个值未通过测试的结果。如果您的程序真的不能继续,那么抛出异常。如果错误是良性的并且您的程序可以以某种方式继续,只需记录错误消息(例如,std::cerr)并继续。

答案 2 :(得分:1)

要回答你的第一个问题,在C ++中没有非常简单的方法可以做到这一点,不过我会在你的问题上留下一些评论,指出一些方法。

对于您的第二个问题,我建议您使用default案例。这就是原因。第一个原因是较弱,但最后两个更强。

  1. 有人可能会明确地将整数转换为枚举值,而不会检查它是否有效。这应该是禁止的,但有时候仍然会发生,如果在代码审查中遗漏了,你应该在运行时捕获这个编程错误。
  2. 您可以从不受信任的外部来源读取struct或其他数据,其中struct包含枚举字段,但忘记对其进行正确验证。不受信任的外部源甚至可以是使用旧版程序保存的文件,其中枚举具有不同的有效值集。
  3. 你可能在某个地方有一个未初始化的枚举。
  4. 即使是这样简单的事情:

    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一个合适的错误消息 - 这是在运行时捕获的编程失败。

    如果这样的失败不是一个选项,你至少应该尝试记录它,至少在调试版本中,这样你就可以发现问题。

    如果无效值对特定的枚举有意义,那么根据它为什么有意义,根据你认为适合的枚举处理它。