为什么我必须显式转换为我指定了基础类型的枚举?

时间:2019-05-20 10:20:00

标签: c++ c++11

我最近了解到可以在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;
}

在这种情况下,我仍然必须显式转换为基础类型才能使用它,那么此功能的目的是什么?

2 个答案:

答案 0 :(得分:2)

这是类型安全功能。隐式转换在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));

更清晰丑陋。演员表的笨拙性质会告诉您“为什么还要这么做?”,回答这个问题应该不太容易。您创建了枚举以通过键入可能的值来关联可能的值,对吧?

答案 1 :(得分:0)

根据this文档页面:

  

没有作用域值的隐式转换   枚举数为整数类型,尽管static_cast可用于   获取枚举器的数值。

因此,为了编译您的代码,您需要显式转换值,即:

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