首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

enumeration declaration

枚举是一个不同的类型,其值被限制在值%28的范围内,请参阅下面的详细信息%29,其中可能包括几个显式命名常量%28“枚举器“%29。常量的值是称为底层类型枚举的。

枚举由明矾,它出现在声明语法。大明矾具有以下语法:

enum-key attr(optional) identifier(optional) enum-base(optional) { enumerator-list(optional) }

(1)

enum-key attr(optional) nested-name-specifier(optional) identifier enum-base(optional) ;

(2)

(since C++11)

1%29枚举类型的定义。

2%29不透明枚举声明*定义枚举类型,但不定义它的枚举数:在此声明之后,类型是一个完整的类型,并且它的大小是已知的。注:显式专业化声明自C++14%29以来,嵌套名称说明符出现在标识符%28之前的唯一情况是类模板的作用域枚举成员。

enum-key

-

one of enum, enum class(since C++11), or enum struct(since C++11)

attr(C++11)

-

optional sequence of any number of attributes

identifier

-

the name of the enumeration that's being declared. If present, and if this declaration is a re-declaration, it may be preceded by nested-name-specifier(since C++11): sequence of names and scope-resolution operators ::, ending with scope-resolution operator. The name can be omitted only in unscoped enumeration declarations

enum-base(C++11)

-

colon (:), followed by a type-specifier-seq that names an integral type (if it is cv-qualified, qualifications are ignored) that will serve as the fixed underlying type for this enumeration type

enumerator-list

-

comma-separated list of enumerator definitions, each of which is either simply an identifier, which becomes the name of the enumerator, or an identifier with an initializer: identifier = constexpr. In either case, the identifier can be directly followed by an optional attribute specifier sequence. (since C++17)

有两种不同的枚举:非作用域枚举%28用枚举键声明enum29%和作用域枚举%28用枚举键声明enum classenum struct29%。

非作用域枚举

enum name { enumerator = constexpr , enumerator = constexpr , ... }

(1)

enum name : type { enumerator = constexpr , enumerator = constexpr , ... }

(2)

(since C++11)

enum name : type ;

(3)

(since C++11)

1%29定义一个非作用域枚举类型,其基础类型不是固定%28--在本例中,基础类型为int或者,如果不是所有枚举数值都可以表示为int,一个实现定义的更大的整数类型,可以表示所有枚举数值。如果枚举数列表为空,则基础类型就好像枚举有一个值为0%29的枚举数。

2%29定义一个非作用域枚举类型,其基础类型是固定的。

3%29非限定范围枚举的不透明枚举声明必须指定基础类型。

每个枚举数成为枚举%27s类型%28的命名常量,即名称%29,在封闭作用域中可见,并且可以在需要常量时使用。

二次

代码语言:javascript
复制
enum Color { red, green, blue };
Color r = red;
switch(r)
{
    case red  : std::cout << "red\n";   break;
    case green: std::cout << "green\n"; break;
    case blue : std::cout << "blue\n";  break;
}

二次

每个枚举数与基础类型的值相关联。在枚举器列表中提供初始化器时,枚举器的值由这些初始化器定义。如果第一个枚举数没有初始化器,则关联的值为零。对于定义没有初始化器的任何其他枚举数,关联的值是前一个枚举数加一个枚举数的值。

二次

代码语言:javascript
复制
enum Foo { a, b, c = 10, d, e = 1, f, g = f + c };
//a = 0, b = 1, c = 10, d = 11, e = 1, f = 2, g = 12

二次

非作用域枚举类型的值为隐式可兑换积分类型。如果基础类型未固定,则可将值从以下列表转换为第一种类型,该列表能够保存其整个值范围:int,,,unsigned int,,,long,,,unsigned long,,,long long,或unsigned long long如果基础类型是固定的,则可以将这些值转换为其提升的基础类型。

二次

代码语言:javascript
复制
enum color { red, yellow, green = 20, blue };
color col = red;
int n = blue; // n == 21

二次

可以转换整数、浮点和其他枚举类型的值,例如static_cast,到任何枚举类型。结果为未指定的%28,直到C++17%29未定义的行为%28,因为C++17%29,如果转换为枚举%27s基础类型的值不在此枚举%27s范围如果基础类型是固定的,则范围基础类型的范围。如果基础类型未固定,则范围最小位字段的所有值都可以容纳目标枚举的所有枚举数。注意,这种转换后的值不一定等于为该类型定义的任何命名枚举数。

二次

代码语言:javascript
复制
enum access_t { read = 1, write = 2, exec = 4 }; // enumerators: 1, 2, 4 range: 0..7
access_t rw = static_cast<access_t>(3);
assert(rw & read && rw & write);

二次

可以省略非作用域枚举的名称:这种声明只将枚举器引入到包围范围中:

二次

代码语言:javascript
复制
enum { a, b, c = 0, d = a + 2 }; // defines a = 0, b = 1, c = 0, d = 2

二次

当非作用域枚举是类成员时,可以使用类成员访问运算符访问其枚举数。.->*

二次

代码语言:javascript
复制
struct X
{
    enum direction { left = 'l', right = 'r' };
};
X x;
X* p = &x;
 
int a = X::direction::left; // allowed only in C++11 and later
int b = X::left;
int c = x.left;
int d = p->left;

二次

Scoped enumerations enum struct|class name { enumerator = constexpr , enumerator = constexpr , ... } (1) enum struct|class name : type { enumerator = constexpr , enumerator = constexpr , ... } (2) enum struct|class name ; (3) enum struct|class name : type ; (4) 1) declares a scoped enumeration type whose underlying type is int (the keywords class and struct are exactly equivalent) 2) declares a scoped enumeration type whose underlying type is type 3) opaque enum declaration for a scoped enumeration whose underlying type is int 4) opaque enum declaration for a scoped enumeration whose underlying type is type Each enumerator becomes a named constant of the enumeration's type (that is, name), which is contained within the scope of the enumeration, and can be accessed using scope resolution operator. There are no implicit conversions from the values of a scoped enumerator to integral types, although static_cast may be used to obtain the numeric value of the enumerator. enum class Color { red, green = 20, blue }; Color r = Color::blue; switch(r) { case Color::red : std::cout << "red\n"; break; case Color::green: std::cout << "green\n"; break; case Color::blue : std::cout << "blue\n"; break; } // int n = r; // error: no scoped enum to int conversion int n = static_cast<int>(r); // OK, n = 21

enum struct|class name { enumerator = constexpr , enumerator = constexpr , ... }

(1)

enum struct|class name : type { enumerator = constexpr , enumerator = constexpr , ... }

(2)

enum struct|class name ;

(3)

enum struct|class name : type ;

(4)

(since C++11)

enum struct|class name { enumerator = constexpr , enumerator = constexpr , ... }

(1)

enum struct|class name : type { enumerator = constexpr , enumerator = constexpr , ... }

(2)

enum struct|class name ;

(3)

enum struct|class name : type ;

(4)

Both scoped enumeration types and unscoped enumeration types whose underlying type is fixed can be initialized from an integer without a cast, using list initialization, if all of the following is true: the initialization is direct-list-initialization the initializer list has only a single element the enumeration is either scoped or unscoped with underlying type fixed the conversion is non-narrowing This makes it possible to introduce new integer types (e.g. SafeInt) that enjoy the same existing calling conventions as their underlying integer types, even on ABIs expressly designed to penalize passing/returning structures by value. enum byte : unsigned char {}; // byte is a new integer type byte b { 42 }; // OK as of C++17 (direct-list-initialization) byte c = { 42 }; // error byte d = byte{ 42 }; // OK as of C++17; same value as b byte e { -1 }; // error struct A { byte b; }; A a1 = { { 42 } }; // error A a2 = { byte{ 42 } }; // OK as of C++17 void f(byte); f({ 42 }); // error enum class Handle : std::uint32_t { Invalid = 0 }; Handle h { 42 }; // OK as of C++17

(since C++17)

  • 初始化是直接列表初始化。
  • 初始化程序列表只有一个元素。
  • 枚举的作用域或者是非作用域,其基础类型是固定的。
  • 转换是不缩小范围的。

这使得引入新的整数类型%28e.g成为可能。SafeInt%29,它享有与其基本整数类型相同的现有调用约定,即使是在ABI上也是如此。

枚举字节:无符号字符{};//字节是一个新的整数类型字节b{42};//OK of C++17%28直接列表-初始化%29字节c={42};//错误字节d=字节{42};//OK截至C++17;与b字节e{-1};//错误结构A{字节b;};A_1={{42};//错误A_2={字节{42};//OK为C++17的空f%28字节%29;F%28{42}%29;//Error枚举类句柄:std::uint 32[医]t{无效=0};句柄h{42};//确定为C++17

%28自C++17%29

二次

代码语言:javascript
复制
#include <iostream>
 
// enum that takes 16 bits
enum smallenum: int16_t
{
    a,
    b,
    c
};
 
 
// color may be red (value 0), yellow (value 1), green (value 20), or blue (value 21)
enum color
{
    red,
    yellow,
    green = 20,
    blue
};
 
// altitude may be altitude::high or altitude::low
enum class altitude: char
{ 
     high='h',
     low='l', // C++11 allows the extra comma
}; 
 
// the constant d is 0, the constant e is 1, the constant f is 3
enum
{
    d,
    e,
    f = e + 2
};
 
//enumeration types (both scoped and unscoped) can have overloaded operators
std::ostream& operator<<(std::ostream& os, color c)
{
    switch(c)
    {
        case red   : os << "red";    break;
        case yellow: os << "yellow"; break;
        case green : os << "green";  break;
        case blue  : os << "blue";   break;
        default    : os.setstate(std::ios_base::failbit);
    }
    return os;
}
 
std::ostream& operator<<(std::ostream& os, altitude al)
{
    return os << static_cast<char>(al);
}
 
int main()
{
    color col = red;
    altitude a;
    a = altitude::low;
 
    std::cout << "col = " << col << '\n'
              << "a = "   << a   << '\n'
              << "f = "   << f   << '\n';
}

二次

产出:

二次

代码语言:javascript
复制
col = red
a = l
f = 3

二次

缺陷报告

以下行为更改缺陷报告追溯应用于先前发布的C++标准。

DR

Applied to

Behavior as published

Correct behavior

CWG 1638

C++14

grammar of opaque enum declaration prohibited use for template specializations

nested-name-specifier permitted

另见

C.数字文件

*。

代码语言:txt
复制
 © cppreference.com

在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。

扫码关注腾讯云开发者

领取腾讯云代金券