C ++枚举是签名还是未签名?

C ++枚举是签名还是未签名? 通过扩展来validation一个input是安全的,通过检查它是否是你的最大值,而忽略> =你的最小值(假设你从0开始,并加1)?

你不应该依赖任何具体的表示。 阅读以下链接 。 此外,该标准说,它是实现定义哪个积分types被用作一个枚举的基础types,除了它不应该大于int,除非某个值不能int或unsigned int。

简而言之:你不能依赖于有符号或无符号的枚举。

让我们来源。 以下是C ++ 03标准(ISO / IEC 14882:2003)文档在7.2-5(枚举声明)中所说的内容:

枚举的基本types是一个整型,可以表示枚举中定义的所有枚举值。 它是实现定义的,其中整型被用作枚举的基础types,除非基础types不应该大于int,除非枚举器的值不能放在int或unsigned int中。

简而言之,你的编译器可以select(显然,如果你的枚举值有一些负值,它会被签名)。

您不应该依赖于他们被签名或未签名。 如果你想使它们明确地有符号或无符号,你可以使用下面的代码:

enum X : signed int { ... }; // signed enum enum Y : unsigned int { ... }; // unsigned enum 

你不应该依赖它是有符号的还是无符号的。 根据标准,实现定义了哪个整型被用作枚举的基础types。 但是在大多数实现中,它是一个有符号的整数。

在C ++中, 强types枚举将被添加,这将允许您指定枚举的types,如:

 enum X : signed int { ... }; // signed enum enum Y : unsigned int { ... }; // unsigned enum 

即使现在,通过使用枚举作为variables或参数types,可以实现一些简单的validation:

 enum Fruit { Apple, Banana }; enum Fruit fruitVariable = Banana; // Okay, Banana is a member of the Fruit enum fruitVariable = 1; // Error, 1 is not a member of enum Fruit // even though it has the same value as banana. 

编译器可以决定枚举是否有符号或无符号。

validation枚举的另一种方法是使用枚举本身作为variablestypes。 例如:

 enum Fruit { Apple = 0, Banana, Pineapple, Orange, Kumquat }; enum Fruit fruitVariable = Banana; // Okay, Banana is a member of the Fruit enum fruitVariable = 1; // Error, 1 is not a member of enum Fruit even though it has the same value as banana. 

即使一些旧的答案有44赞成,我倾向于不同意所有这些。 总之,我不认为我们应该关心枚举的underlying type

首先,C ++ 03枚举types是一个独特的types,它没有符号概念。 因为从C ++ 03标准的dcl.enum

 7.2 Enumeration declarations 5 Each enumeration defines a type that is different from all other types.... 

所以当我们谈论一个枚举types的符号时,比如使用<运算符比较两个枚举操作数时,我们实际上是在讨论将枚举types隐式转换为某种整型。 这是整体types的重要标志 。 当把enum转换为整型时,这个陈述适用于:

 9 The value of an enumerator or an object of an enumeration type is converted to an integer by integral promotion (4.5). 

显然,枚举的基本types与整体推广没有任何关系。 由于标准定义了这样的整体推广:

 4.5 Integral promotions conv.prom .. An rvalue of an enumeration type (7.2) can be converted to an rvalue of the first of the following types that can represent all the values of the enumeration (ie the values in the range bmin to bmax as described in 7.2: int, unsigned int, long, or unsigned long. 

所以,枚举types是否变成带signed intunsigned int取决于signed int是否可以包含定义的枚举符的所有值,而不是枚举的基础types。

看到我的相关问题转换为积分types后,C ++枚举types的符号不正确

将来,使用C ++ 0x, 强types枚举将可用,并具有几个优点(例如types安全,显式基础types或显式范围)。 有了这个,你可以更好地保证types的标志。

除了其他人已经谈过的签名/未签名之外,以下是关于枚举types范围的标准:

7.2(6):“对于e(min)是最小枚举数并且e(max)最大的枚举,枚举的值是在b(min)到b(max ),其中b(min)和b(max)分别是可以存储e(min)和e(max)的最小位域的最小值和最大值。可以定义一个枚举值,由它的任何一个普查员“。

举个例子:

 enum { A = 1, B = 4}; 

定义了一个枚举types,其中e(min)是1,e(max)是4.如果底层types是带符号的int,那么最小的所需位域有4位,如果你的实现中的整数是二进制补码,那么枚举是-8到7.如果底层types是无符号的,那么它有3位,范围是0到7.检查你的编译器文档,如果你关心的话(例如,如果你想将枚举数以外的整数值转换为枚举types,那么你需要知道该值是否在枚举的范围内 – 如果没有得到的枚举值是未指定的)。

是否这些值是有效的input到您的函数可能是一个不同的问题,它们是否是枚举types的有效值。 你的检查代码可能是担心前者而不是后者,所以在这个例子中至less应该检查> = A和<= B。