具有非固定类型的枚举范围定义的动机

时间:2014-12-24 05:54:16

标签: c++ enums

以下文字来自C++14 N4296 working draft 7.2/8 [dcl.enum]

  

对于其基础类型是固定的枚举,其值为   枚举是基础类型的值。否则,为了   枚举,emin是最小的枚举数,emax是。{   最大值,枚举值是范围内的值   bmin到bmax,定义如下:对于二进制补码,设K为1   表示和0表示一个补码或符号幅度   表示。 bmax是大于或等于的最小值   max(|emin| − K, |emax|)并且等于2M − 1,其中M是非负数   整数。如果bmin为非负数且emin,则−(bmax + K)为零   否则。

让我们通过例子来考虑它的工作原理。下面声明的枚举具有非固定的基础类型:

enum E { x = -2, y = 2 }

假设实现定义了signed magnitude表示,而不是K = 0。现在emin = -2, emax = 2bmax = 2^2 -1 = 3bmin = 2。因此,枚举值的范围是2到3.这是什么意思?该间隔应告诉我们什么?我们不能将间隔中的值赋给枚举类型的变量。观看:

#include <iostream>

enum A { x = -2, y = 2 };

A a = 2; // cannot initialize a variable of type 'A' with an rvalue of type 'int'
A b = 3; // cannot initialize a variable of type 'A' with an rvalue of type 'int'

int main(){ }

DEMO

1 个答案:

答案 0 :(得分:1)

您的范围不正确

  如果emin是非负的,则

bmin为零,否则 - (bmax + K)

bmax = 3(即2 2 -1),因此bmin = - (3 + 0)或-3

  

这是什么意思?该间隔应告诉我们什么?

脚注96告诉你:

  

96)这组值用于定义枚举类型的提升和转换语义。它不排除枚举类型的表达式具有超出此范围的值。

由于枚举的基础类型总是积分的,因此范围也隐含地限制了任何给定enum的可用不同值的数量(在这种情况下为7,但请参阅下文,了解当值超出此范围时会发生什么)。

此公式产生的最小可能类型可以保存选择的每个值作为基础类型。它还允许将范围比其基础类型短的enum的值打包到位域中。

  

我们无法将间隔中的值分配给枚举类型

的变量

是的,你可以

A a = static_cast<A>(2);

如果你在枚举范围之外输出一个整数,那么你最终会得到一个未指定的(即毫无价值但有效)的值

[expr.static.cast]

  

10可以将整数或枚举类型的值显式转换为枚举类型。如果原始值在枚举值(7.2)的范围内,则该值不变。否则,结果值未指定(可能不在该范围内)。[...]

缺陷1766在下一版标准

中将此加强为未定义的行为
  

10可以将整数或枚举类型的值显式转换为完整的枚举类型。如果原始值在枚举值(7.2)的范围内,则该值不变。否则,行为未定义。 [...]

无论哪种方式,你几乎总是不应该首先将整数转换为枚举。