删除枚举元素的重复项

Remove duplication of enumerated elements

本文关键字:枚举 元素 删除      更新时间:2023-10-16

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

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)鉴于CheckEnumValidity()具有myEnum类型的参数,我是否应该在上述switch语句中default抛出异常(或返回false)的行为?

笔记:

C++ 11 不适用于我的应用程序。

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

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

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

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

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

至于你的检查函数是否应该抛出异常,这归结为一个值测试失败的后果是什么。 如果您的程序确实不应该继续,则引发异常。 如果错误是良性的,并且您的程序可以以某种方式继续,只需记录错误消息(例如std::cerr)并继续。

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

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

  1. 有人可能会将整数显式转换为枚举值,而不检查它是否有效。这应该是被禁止的,但有时仍然会发生,如果在代码审查中错过了这个编程错误,你应该在运行时捕获它。
  2. 您可能会从不受信任的外部源读取struct或其他数据,其中该struct包含枚举字段,而忘记正确验证它。不受信任的外部源甚至可能是与旧版本的程序一起保存的文件,其中枚举具有一组不同的有效值。
  3. 您可能在某处有一个未初始化的枚举。

即使是这样简单的事情:

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 - 这是在运行时捕获的编程失败。

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

如果无效值对特定枚举有意义,则根据其有意义的原因,按照您认为适合该枚举的方式处理它。