C++ 我们真的需要吗;“枚举类”;在C++;11?

C++ 我们真的需要吗;“枚举类”;在C++;11?,c++,enums,c++11,language-lawyer,C++,Enums,C++11,Language Lawyer,当我们有 struct E { enum E_ { HELLO }; }; // 'E' is inheritable 那我们为什么需要, enum class E { HELLO }; // 'E' is not inheritable IMO第二版没有提供比第一版更多的功能。我不认为引入enum类只是为了节省2个大括号{}!我是否遗漏了任何重要方面 作为一个小问题,enum class和enum struct之间除了语法(因为两者都有public访问说明符)之外还有什么区别吗?在第一种

当我们有

struct E { enum E_ { HELLO }; }; // 'E' is inheritable
那我们为什么需要,

enum class E { HELLO };  // 'E' is not inheritable
IMO第二版没有提供比第一版更多的功能。我不认为引入
enum类
只是为了节省2个大括号
{}!我是否遗漏了任何重要方面


作为一个小问题,
enum class
enum struct
之间除了语法(因为两者都有
public
访问说明符)之外还有什么区别吗?

在第一种情况下,
HELLO
的类型不是
E
,而在第二种情况下,
HELLO
的类型是
E

要很好地说明这一点的重要性,请参阅Howard Hinnant的答案

enum class
enum struct
根据C++0x FDIS§7.2/2,在语义上是“等价的”(即相同的)

我们真的需要C++0x中的“枚举类”吗

不,我们不“需要”
enum类。我们可以通过其他方式获得足够等效的功能。但从逻辑上讲,我们不需要C++中的很多东西。我们不“需要”虚拟函数和继承,因为我们可以用vtables等手动实现它。我们不“需要”成员函数;这些可以通过让它们接受额外的参数来模拟

语言特性的存在使程序员的生活更加轻松。仅仅因为某些事情可以手动完成并不意味着它应该这样做

enum类
具有以下属性:

  • 这很容易理解;它反映了枚举在其他语言中的工作方式
  • 它对编译器编写人员的要求相对较少。将实现工作与r值引用、varadic模板或用户定义的文本等功能进行对比
  • 它不会以任何方式破坏语法。一开始看到
    enum类
    可能有点奇怪,但对于大多数新特性来说都是如此。一旦你习惯了,就没事了
  • 它是100%向后兼容的,因为它不会重新定义常规枚举的工作方式。旧式枚举的工作原理与以前相同
  • 它使您不必编写大量样板代码。Boost有一个宏来创建枚举类定义的效果。如果没有这个宏,您必须花费相当多的精力才能使所有角落案例正常工作。即便如此,还是得有人编写和调试宏

  • 因此,不,我们不“需要”它们。但是它们仍然是对语言的一个很好的补充。

    除了前面提到的以外,
    枚举类的一个优点是更好的类型安全性-枚举类的
    枚举数不会隐式转换为整数。

    我认为您需要了解这些新枚举的其他优点

    • 用户定义的大小
    • 作用域值(不再对值进行一般作用域填充)
    • 没有到整数类型的隐式转换
    • 枚举的前向声明(API中枚举的最大改进)

    是的,我们有。看来以前没有人指出这一点。如果需要设置一个<代码> EnUM <代码>的大小,并且按照C++标准保持不变?代码>枚举类
    可以执行。并且具有前面提到的类型安全性。它可以减少代码中可能出现的错误,并将
    int
    enum
    s混合在一起。对我来说,它们从来都不是一回事。太神了e、 例如,
    enum类foo:int16\u t{…}
    我确信每个成员都是
    int16\u t
    的一员,而不是由实现决定什么对我来说“更好”

    编辑:


    此外,列表中可以有重复的值(而不是名称)。这取决于上下文。

    在第一个示例中,如何引用
    E
    中的枚举类型?您可能会对阅读感兴趣。普通枚举不是类型安全的,有一个实现定义的基础类型,没有强作用域@zneak:您可以添加
    typee::E_defenumtype我读了答案。通过使用
    my_enum::type
    ;重载
    操作符ostream
    ,可以很容易地解决这个问题。这只是一个很小的变化,
    enum类
    本可以很容易地提供。但它仍然值得吗?是的,它肯定仍然值得:它是语言的一个小型、自包含的补充,支持更干净地使用枚举,并替换了许多乱七八糟的东西(其中许多是不正确的)。它不像右值引用、lambda表达式或变量模板那样改变游戏规则,但这并不意味着它不是一个有用的功能。“这个问题本可以很容易地解决”。。。但是以编译时间常数为成员变量的代价(加上,虽然不重要,必须为结构保持一个地址),即使所有数据是常量的,或者根本没有数据,编译器仍然必须准备好,尝试使用C++的地址,它不能确定你不会。或者,在新版本中是否存在一种很好的方法来指定变量应具有枚举类型,在该类型上应使用按位运算符?我发现的唯一方法是要么将变量声明为“int”(仅使用enum来命名值),要么显式定义所有应该在enum上工作的运算符。这样的操作符在默认情况下不在枚举上工作,看起来像是从C到C++的更大的“破”变化之一。@ SuffCAT,可能应用了这种限制,因为直观地期望枚举类型的值等于其枚举器之一(枚举器的位组合不适合)。因此,当您将枚举数转换为整数时(例如,为了执行逐位运算),它实际上不再是枚举。@Kos:这确实是一个概念,但在许多情况下,一个变量/字段的逻辑含义是