C++枚举的签署或无符号?通过扩展它是安全的验证输入通过检查,这是 <=你的最大价值,并留出>=您的分数值(假设你开始在0和加1)?

有帮助吗?

解决方案

您不应该依赖任何特定的陈述。请阅读以下链接。此外,标准表示它是实现定义的,哪个整数类型用作枚举的基础类型,除了它不应大于int,除非某些值不能适合int或unsigned int。

简而言之:你不能依赖于签名或未签名的枚举。

其他提示

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

  

枚举的基础类型   是一种可以代表的整体类型   中定义的所有枚举器值   枚举。它是   实现 - 定义哪个积分   type用作底层类型   列举除了   基础类型不应该更大   比int除非a的值   枚举器不能适合int或   unsigned int。

简而言之,您的编译器可以选择(显然,如果您的某些枚举值有负数,则会被签名)。

您不应该依赖签名或未签名。如果要明确签名或未签名,可以使用以下命令:

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

您不应该依赖签名或未签名。根据标准,它是实现定义的,其中整数类型用作枚举的基础类型。但是,在大多数实现中,它是一个有符号整数。

在C ++ 0x中将添加强类型枚举将允许您指定枚举的类型,例如:

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

即使是现在,也可以通过将枚举用作变量或参数类型来实现一些简单的验证:

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.

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

验证枚举的另一种方法是使用枚举本身作为变量类型。例如:

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枚举的类型是不同类型的自己没有概念的标志。自从C++03标准 dcl.enum

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

所以当我们谈论的是签名的一枚举的类型,说进行比较时,2枚举的操作数的使用 < 操作者,我们实际上谈论的是隐含地将枚举的类型,一些整体的类型。 它的这种整体类型的事项.及时转换枚举的组成型,这一说法适用于:

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

而且,很显然,基础类型的枚举得到做什么与整体促进。由于标准定义的组成促进这样的:

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
(i.e. the values in the range bmin to bmax as described in 7.2: int, unsigned int, long, or unsigned long.

因此,是否枚举的类型变 signed intunsigned int 取决于是否 signed int 可以包含所有价值观定义的统计员,而不是基础型的枚举。

看到我的有关问题 签署C++枚举类型的错误之后转换为整体型

将来,使用C ++ 0x,强类型枚举将可用并具有多个优点(例如类型安全,显式底层类型或显式范围)。有了这个,你可以更好地确定类型的标志。

除了其他人已经说过的有关签名/未签名的内容之外,以下是关于枚举类型范围的标准说明:

7.2(6):<!>;对于枚举,其中e(min)是最小的枚举数且e(max)是最大的,枚举的值是b范围内的基础类型的值(min)到b(max),其中b(min)和b(max)分别是可以存储e(min)和e(max)的最小位域的最小值和最大值。可以定义一个枚举,该枚举的值不是由任何枚举器定义的。<!> quot;

例如:

enum { A = 1, B = 4};

定义了枚举类型,其中e(min)为1,e(max)为4.如果基础类型为signed int,则所需的最小位域为4位,如果实现中的int为2的补码,则枚举的有效范围是-8到7.如果基础类型是无符号的,那么它有3位,范围是0到7.如果你关心,请检查编译器文档(例如,如果你想要转换除了枚举类型的枚举器,然后您需要知道该值是否在枚举范围内 - 如果不是未指定的结果枚举值。

这些值是否是函数的有效输入可能与它们是否是枚举类型的有效值有所不同。您的检查代码可能会担心前者而不是后者,因此在此示例中至少应该检查<!> gt; = A和<!> lt; = B.

使用std::is_signed<std::underlying_type +作用域枚举默认为int

进行检查

https://en.cppreference.com/w/cpp/language/enum 暗示:

的main.cpp

#include <cassert>
#include <iostream>
#include <type_traits>

enum Unscoped {};
enum class ScopedDefault {};
enum class ScopedExplicit : long {};

int main() {
    // Implementation defined, let's find out.
    std::cout << std::is_signed<std::underlying_type<Unscoped>>() << std::endl;

    // Guaranteed. Scoped defaults to int.
    assert((std::is_same<std::underlying_type<ScopedDefault>::type, int>()));

    // Guaranteed. We set it ourselves.
    assert((std::is_same<std::underlying_type<ScopedExplicit>::type, long>()));
}

GitHub上游

编译并运行:

g++ -std=c++17 -Wall -Wextra -pedantic-errors -o main main.cpp
./main

输出:

0

在Ubuntu 16.04,GCC 6.4.0上测试。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top