为什么我必须明确地施放我指定基础类型的枚举

Why do I have to explicitly cast an enum that I have specified the underlying type for?

本文关键字:类型 枚举 施放我 为什么      更新时间:2023-10-16

我最近了解到我可以在C 11中指定枚举者的基础类型。

我注意到我不能例如使用具有基础类型uint16_t的枚举器作为uint16_t参数的参数。请参阅以下示例:

#include <stdint.h>
enum class Apples : uint16_t
{
    GRANNY_SMITH = 1
};
class AppleWatcher
{
    uint16_t m_apple;
public:
    AppleWatcher(const uint16_t apple) : m_apple(apple) {};
};
int main()
{
    AppleWatcher(static_cast<uint16_t>(Apples::GRANNY_SMITH));  // This works
    AppleWatcher(Apples::GRANNY_SMITH); // Compiler error here
    return 0;
}

在这种情况下,我仍然必须明确施放基础类型才能使用它,那么此功能的目的是什么?

这是一种类型的安全功能。隐式转换在C 中有相关问题的悠久历史,请看一下Stephen DeWhurst的书" C Gotchas" - 最长的一章是转换。

回想一下,枚举不过是将恒定值绑定到可理解名称的一种方式。这样,就有一组有限的可能值集,并且通过隐式转换,您可以大大扩展域而无需发出任何通知。示例:

void f(uint16_t arg); // arg can have 65536 different values
enum class Apples  : uint16_t { GRANNY_SMITH = 1 }; // one possible value

如果此编译:

f(Apples::GRANNY_SMITH);

您刚刚放弃了限制性,而无需通知。相反,

f(static_cast<uint16_t>(Apples::GRANNY_SMITH));

更清晰,更丑。演员的笨拙性告诉您:"你为什么要这么做?",回答这个问题不太容易。您创建了枚举来引用可能的值,通过输入其关联名称,对呢?

根据此文档页面:

没有范围值的隐式转换 枚举器到整体类型,尽管static_cast可以使用 获取枚举器的数字值。

因此,为了编译您的代码,您需要明确施放该值,即:

AppleWatcher(static_cast<uint16_t>(Apples::GRANNY_SMITH));