将枚举转换为值的正确方法

Correct way to convert an enum to value

本文关键字:方法 枚举 转换      更新时间:2023-10-16

我正在做一个项目,该项目定义了很多枚举,如下所示:

enum BundleSize
{
    BUNDLE_SIZE_5 = 5,
    BUNDLE_SIZE_10 = 10,
    BUNDLE_SIZE_107 = 107,
};

我写了一个函数来从中获取值,如下所示:

int convertBundleSizeEnumToVal(BundleSize b)
{
    switch(b)
    {
        case BUNDLE_SIZE_5: return 5; break;
        case BUNDLE_SIZE_10: return 10; break;
        case BUNDLE_SIZE_107: return 107; break;
        default: // handle appropriately and error out
    }
}

意识到我真的不需要转换器(方法 1 和 2 都在下面工作):

BundleSize b = getRandomBundleSize();
printf("The size is %dn", convertBundleSizeEnumToVal(b)); // method 1
printf("The size is %dn", b); // method 2

但我觉得方法 1 仍然是执行此操作的"正确"方法,因为将来可能会出现这样的事情:

enum BundleSize
{
    BUNDLE_SIZE_5 = 5,
    BUNDLE_SIZE_5_POINT_5 = 6,
    BUNDLE_SIZE_10 = 10,
    BUNDLE_SIZE_107 = 107,
};

现在有效地破坏了方法 2 而没有明显的运行时错误,而方法 1 至少会在默认开关情况下捕获问题。

我很好奇人们认为处理这些转换的正确方法是什么。

您可以使用

static_cast运算符:

static_cast<int>(b)

IMO,这是"正确的"。您不应该定义函数来将每个可能的枚举变体转换为整数,尤其是对于大型枚举。

实际上,您使用的是简单的enum,因此您可以简单地使用枚举变量作为值。

对于enum class(枚举的严格版本),您应该使用 static_cast 将枚举转换为值。

您可以将函数简化为:

int convertBundleSizeEnumToVal(BundleSize b)
{
    switch(b)
    {
        case BUNDLE_SIZE_5:
        case BUNDLE_SIZE_10:
        case BUNDLE_SIZE_107:
            return b;
        default: // handle appropriately and error out
    }
}

方法 2 被破坏,因为基础的enum类型不一定是 int,因此格式说明符 %d 可能是错误的,程序的行为可能是未定义的。

您可以先将枚举值强制转换为 int,只要不使用高于 int 表示的值,它就是正确的。可以使用static_cast或显式强制转换。或者,您可以使用隐式转换:

int value = getRandomBundleSize();
printf("The size is %dn", b);

关于你应该使用哪个,这取决于你需要什么。如果您认为以后添加的枚举值不应该通过convertBundleSizeEnumToVal进行转换,而应该导致错误,那么方法 1 确实更胜一筹。

如果您希望转换所有枚举值,则该函数容易出错,因为您必须记住每次添加新值时添加一个大小写。在这种情况下,方法 2 更胜一筹。