【问题标题】:C++11 "enumerated types" (17.5.2.1.2)C++11“枚举类型”(17.5.2.1.2)
【发布时间】:2013-03-31 08:47:35
【问题描述】:

引用 C++11 标准(17.5.2.1.2 枚举类型):

1 第 27 条中定义的几种类型是枚举类型。每个枚举类型都可以实现为枚举或枚举的同义词(例如整数类型,具有常量整数值 (3.9.1))。

2 枚举类型enumerated可以写成:

enum enumerated { V0 , V1 , V2 , V3 , ..... };
static const enumerated C0 (V0 );
static const enumerated C1 (V1 );
static const enumerated C2 (V2 );
static const enumerated C3 (V3 );
.....

3 这里,名称 C0、C1 等表示此特定枚举类型的枚举元素。所有这些元素都有不同的值。

这样的“枚举类型”之一是来自类 ios_base(27.5.3 类 ios_base)的“seekdir”:

// 27.5.3.1.5 seekdir
typedef T4 seekdir;
static constexpr fmtflags beg = unspecified ;
static constexpr fmtflags cur = unspecified ;
static constexpr fmtflags end = unspecified ;

27.5.3.1.5 类型 ios_base::seekdir [ios::seekdir]

typedef T4 seekdir;

1 seekdir 类型是枚举类型 (17.5.2.1.2),包含表 126 中指示的元素。

所以,需要这些静态 const 和 constexpr 成员的唯一原因是因为“枚举类型”允许实现为整数类型(即,当 enumerated 为 int 时,我们需要在适当位置定义常量枚举数),对吧?

问题 1。如果库供应商决定将 seekdir 实现为枚举,他是否仍需要为枚举值定义静态常量?

问题 2。为什么首先允许“枚举类型”实现为整数类型? IE。当没有这些静态常量成员的枚举实现(并且在 C++11 中枚举可以具有任何底层整数类型)可能比整数类型实现更糟糕时?

【问题讨论】:

  • 额外问题:为什么在ios_base 的概要中使用static constexpr fmtflags beg = unspecified ; 而不是static constexpr seekdir beg = unspecified ;? - 我刚刚向标准组的人报告了这件事,似乎是一个错字。
  • @Daniel “向标准的人报告了这一点” - 很酷,你是怎么做到的? :) 另外,TBH,即使在复制粘贴那句话之后,我自己也没有注意到那个错字。
  • 我给标准封面页上给出的地址写了一封电子邮件。我猜对于这样一个明显的错字应该足够好。一般来说,你应该关注these guidelines
  • @DanielFrey - 标准的封面上没有电子邮件地址。我假设您的意思是您用作实际标准的替代品的草案。
  • @PeteBecker:哎呀,正确 :)

标签: c++ c++11 enums


【解决方案1】:

编写标准时,强类型枚举不可用,而普通 enum 的问题在于,它们的内部类型未指定,并且可能更改取决于编译器开关。 p>

对于seekdir,它可以是intbyte(例如),两者都是有效的表示。 GCC 有一个命令行选项(--short-enums-fshort-enums),默认情况下它会使用 int 作为所有 enums 的最小类型,但使用该选项它将使用可以包含的最小类型所有值。

这意味着如果在函数签名中使用真正的enum,则符号可能会更改,您需要重新编译所有内容。这就是标准允许其他选项的原因,标准库实现控制类型很重要的原因,这就是允许使用特定整数类型的原因。

【讨论】:

  • @Daniel 您是否暗示在过去(C++11 之前)GCC 中的标准库实现使用整数类型而不是枚举作为 seekdir,因为您描述的问题?
  • @PowerGamer,在 GCC 的特定情况下,不,只要我记得,seekdir 一直是 enum _Ios_Seekdir 的 typedef
  • @PowerGamer:我没有暗示任何具体内容,因为每个编译器和标准库都可以找到其他方法来处理它。在 libstdc++ 的情况下,我认为这是 _S_ios_seekdir_end = 1L << 16ios_base.h 中的原因,因此即使使用 -fshort-enums,它也永远不会减少到小于 int 的任何值。
  • @DanielFrey 由于像_S_ios_seekdir_end = 1L << 16 这样的小技巧解决了“重新编译所有内容”的需要,因此您在答案中描述的内容不能算作整数类型优于枚举的优势(即使对于 C+ +11 个枚举)。我会接受皮特的回答(但无论如何感谢您的贡献)。
  • @PowerGamer:好的,我知道我的措辞有点太强了,所以我修正了它。请注意,我试图回答为什么标准允许它的问题,而不是真的需要它。
【解决方案2】:

要求枚举类型值的对象的最初原因是为了获取它们的地址。这总是让我觉得很傻,但在标准化的早期阶段存在相当多的过度设计。

【讨论】:

  • 有趣的是,我什至将它作为我的答案的一部分并将其编辑掉,因为我无法为它的生活想到一个可能有用的例子:)
  • @Pete 那么在 C++11 中允许整数类型用于“枚举类型”并要求静态 const 类成员只是向后兼容的另一种情况?即使供应商决定使用前。 "enum seekdir: int" 他还需要定义那些静态的 constexpr 成员吗?
  • @PowerGamer,是的,该标准需要一个实现来定义具有地址的命名对象,它不能只定义枚举器。
猜你喜欢
  • 1970-01-01
  • 2013-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多