C++11中enum class的使用

枚举类型(enumeration)使我们可以将一组整型常量组织在一起。和类一样,每个枚举类型定义了一种新的类型。枚举属于字面值常量类型。

C++包含两种枚举:限定作用域的和不限定作用域的。这里主要介绍限定作用域的。不限定作用域的使用可以参考: http://blog.csdn.net/fengbingchun/article/details/51778977   。

C++11新标准引入了限定作用域的枚举类型(scoped enumeration)。定义限定作用域的枚举类型的一般形式是:首先是关键字enum class(或者等价地使用enum struct),随后是枚举类型名字以及用花括号括起来的以逗号分隔的枚举成员(enumerator)列表,最后是一个分号。

枚举作用域(enumeration scope)是指枚举类型的成员的名字的作用域,起自其声明之处,终止枚举定义结束之处。C语言规定,枚举类型的成员(enumerator)的可见范围被提升至该枚举类型所在的作用域内。这被认为有可能污染了外部的作用域,为此,C++11引入了枚举类(enum class)解决此问题。

定义不限定作用域的枚举类型(unscoped enumeration)时省略掉关键字class(或struct),枚举类型的名字是可选的。

如果enum是未命名的,则我们只能在定义该enum时定义它的对象。和类的定义类似,我们需要在enum定义的右侧花括号和最后的分号之间提供逗号分隔的声明列表。

枚举成员:在限定作用域的枚举类型中,枚举成员的名字遵循常规的作用域准则,并且在枚举类型的作用域外是不可访问的。与之相反,在不限定作用域的枚举类型中,枚举成员的作用域与枚举类型本身的作用域相同。

默认情况下,枚举值从0开始,依次加1.不过我们也能为一个或几个枚举成员指定专门的值。枚举值不一定唯一。如果我们没有显示地提供初始值,则当前枚举成员的值等于之前枚举成员的值加1.枚举成员是const,因此在初始化枚举成员时提供的初始值必须是常量表达式。也就是说,每个枚举成员本身就是一条常量表达式,我们可以在任何需要常量表达式的地方使用枚举成员。类似的,我们也可以将一个enum作为switch语句的表达式,而将枚举值作为case标签。出于同样的原因,我们还能将枚举类型作为一个非类型模板形参使用;或者在类的定义中初始化枚举类型的静态数据成员。

和类一样,枚举也定义新的类型:只要enum有名字,我们就能定义并初始化该类型的成员。要想初始化enum对象或者为enum对象赋值,必须使用该类型的一个枚举成员或者该类型的另一个对象

一个不限定作用域的枚举类型的对象或枚举成员自动地转换成整型。因此,我们可以在任何需要整型值的地方使用它们。而限定作用域的枚举类型不会进行隐式转换

指定enum的大小:尽管每个enum都定义了唯一的类型,但实际上enum是由某种整数类型表示的。在C++11标准中,我们可以在enum的名字后加上冒号以及我们想在该enum中使用的类型。如果我们没有指定enum的潜在类型,则默认情况下限定作用域的enum成员类型是int。对于不限定作用域的枚举类型来说,其枚举成员不存在默认类型,我们只知道成员的潜在类型足够大,肯定能够容纳枚举值。如果我们指定了枚举成员的潜在类型(包括对限定作用域的enum的隐式指定),则一旦某个枚举成员的值超出了该类型所能容纳的范围,将引发程序错误。

指定enum潜在类型的能力使得我们可以控制不同实现环境中使用的类型,我们将可以确保在一种实现环境中编译通过的程序所生成的代码与其他实现环境中生成的代码一致。

枚举类型的前置声明:在C++11新标准中,我们可以提前声明enum。enum的前置声明(无论隐式地还是显示地)必须指定其成员的大小。不限定作用域的,必须指定成员类型。限定作用域的枚举类型可以使用默认成员类型int。因为不限定作用域的enum未指定成员的默认大小,因此每个声明必须指定成员的大小。对于限定作用域的enum来说,我们可以不指定其成员的大小,这个值被隐式地定义成int。和其它声明语言一样,enum的声明和定义必须匹配,这意味着在该enum的所有声明和定义中成员的大小必须一致。而且,我们不能在同一个上下文中先声明一个不限定作用域的enum名字,然后再声明一个同名的限定作用域的enum。

形参匹配与枚举类型:要想初始化一个enum对象,必须使用该enum类型的另一个对象或者它的一个枚举成员。因此,即使某个整型值恰好与枚举成员的值相等,它也不能作为函数的enum实参使用。不限定作用域的枚举类型,潜在类型因机器而异。尽管我们不能直接将整型值传给enum实参,但是可以将一个不限定作用域的枚举类型的对象或枚举成员传给整型形参。此时,enum的值提升成int或更大的整型,实际提升的结果由枚举类型的潜在类型决定。

The enum classes("new enums",  "strong enums") address three problems with traditional C++ enumerations:

1. conventional enums implicitly convert to int, causing errors when someone does not want an enumeration to act as an integer.

2. conventional enums export their enumerators to the surrounding scope, causing name clashes.

3. the underlying type of an enum cannot be specified, causing confusion,compatibility problems, and makes forward declaration impossible.

The new enums are "enum class" because they combine aspects of traditional enumerations (names values) with aspects of classes (scoped members and absense of conversions).

         C++ has two kinds of enum: enum classes,Plain enums.

下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:

#include "enum_class.hpp"
#include <iostream>namespace enum_class_ {typedef short int16_t;// reference: http://en.cppreference.com/w/cpp/language/enum
// 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 test_enum_class_1()
{color col = red;altitude a;a = altitude::low;std::cout << "col = " << col << '\n'<< "a = " << a << '\n'<< "f = " << f << '\n';return 0;
}// reference: https://stackoverflow.com/questions/18335861/why-is-enum-class-preferred-over-plain-enum
// C++ has two kinds of enum: enum classes, Plain enums
enum Color { red1, green1, blue1 };                    // plain enum
enum Card { red_card, green_card, yellow_card };    // another plain enum
enum class Animal { dog, deer, cat, bird, human };  // enum class
enum class Mammal { kangaroo, deer, human };        // another enum classint test_enum_class_2()
{// examples of bad use of plain enums:Color color = Color::red1;Card card = Card::green_card;int num = color;    // no problemif (color == Card::red_card) // no problem (bad)std::cout << "bad" << std::endl;if (card == Color::green1)   // no problem (bad)std::cout << "bad" << std::endl;// examples of good use of enum classes (safe)Animal a = Animal::deer;Mammal m = Mammal::deer;//int num2 = a;   // error//if (m == a)     // error (good)//	std::cout << "bad" << std::endl;//if (a == Mammal::deer) // error (good)//	std::cout << "bad" << std::endl;return 0;
}// reference: http://www.learncpp.com/cpp-tutorial/4-5a-enum-classes/
int test_enum_class_3()
{enum class Color { // "enum class" defines this as an scoped enumeration instead of a standard enumerationRED, // RED is inside the scope of ColorBLUE};enum class Fruit {BANANA, // BANANA is inside the scope of FruitAPPLE};Color color = Color::RED; // note: RED is not directly accessible any more, we have to use Color::REDFruit fruit = Fruit::BANANA; // note: BANANA is not directly accessible any more, we have to use Fruit::BANANA//if (color == fruit) // compile error here, as the compiler doesn't know how to compare different types Color and Fruit//	std::cout << "color and fruit are equal\n";//else//	std::cout << "color and fruit are not equal\n";if (color == Color::RED) // this is okaystd::cout << "The color is red!\n";else if (color == Color::BLUE)std::cout << "The color is blue!\n";//std::cout << color; // won't work, because there's no implicit conversion to intcolor = Color::BLUE;std::cout << static_cast<int>(color) << std::endl; // will print 1return 0;
}} // namespace enum_class_

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/432273.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

亿T算力量子计算机,终于,中国实现“量子计算优越性”,算力比最快超算快一百万亿倍...

就在今天12月4日&#xff0c;一篇由中国科学技术大学潘建伟、陆朝阳等组成的量子计算研究团队&#xff0c;发表在国际顶级科技学术期刊《Science》上的研究成果《使用光子的量子计算优势》&#xff0c;正式宣告中国终于实现了“量子计算优越性”。采用论文中所述量子技术构建的…

查找场景中的actor

UWorld* world GetWorld();for (TActorIterator<AMyActor> It(world, AMyActor::StaticClass()); It; It){AMyActor* actor *It;if (actor ! NULL){}}

Exception from HRESULT: 0x800A03EC

Exception from HRESULT: 0x800A03EC 分类&#xff1a; asp.net 2013-03-04 18:16 1191人阅读 评论(0) 收藏 举报 Exception from HRESULT: 0x800A03EC 在读取Excel文件时&#xff0c;出现这样的一个异常&#xff0c;搞很长时间&#xff0c;最后发现犯了一个愚蠢的低级错误&am…

学校计算机教室安全预案,小学校园微机室安全事故应急疏散预案

小学校园微机室安全事故应急疏散预案提要:若室内因线路故障或其它不可预知因素发生火灾时,应立即疏散学生并关闭电源,用灭火器及其它有效方法进行灭火更多文章来源自 房 地产e网小学校园微机室安全事故应急疏散预案微机室是对学生进行信息技术教学的课堂,是现代课堂教学的一个重…

uva11361数位dp

挺裸的 &#xff0c;只要注意到当k超过9*10 就直接输出0就可以了。 #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib…

TArray

1. 遍历 for&#xff08;auto i : MyTArray){i-> or *i} 2 找到最大值的索引 int32 IndexOfMax(TArray<float> Array) {int32 HighestIndex 0;for (int32 Counter 0; Counter < Array.Num(); Counter){if (Counter > 0){if ([]() { return (Array[Coun…

小学数学加减法测试软件,儿童数学加法运算火箭(测试版)

儿童数字加法运算火箭是一部益智早教、启蒙幼儿学习基础算术的免费学习机&#xff0c;它可以更好的启发刚入门学习数数的宝宝&#xff0c;开拓小孩的计算思维&#xff0c;锻炼幼儿对数字的敏感性&#xff0c;让幼小的小朋友们也可以拥有超快口算、速算、心算一样的能力&#xf…

OpenGL版本与OpenGL扩展机制

1 opengl的版本区别&#xff08;在opengl官方文档中有详细说明&#xff09; 针对Opengl不同版本的升级是主要是扩展指令集。 现在版本是4.0啦 1.1 opengl1.1 1995年&#xff0c;SGI推出了更为完善的OpenGL 1.1版本。OpenGL 1.1的性能比1.0版提高甚多。其中包括改进打印…

PHP编写命令行脚本和后台运行程序的注意事项

在一些场合(如开发,测试), 可能需要使用PHP编写一些命令行的处理脚本,或者是长时间后台运行的任务, 需要注意以下准则: 准则1. 尽量避免使用PHP编写后台运行程序, 尤其是类似while(true){….} 这种循环的处理脚本. 比如,有时候我们需要定期检查数据库,然后有数据进行处理,没有数…

沃尔沃挖机计算机故障,沃尔沃挖掘机常见故障及原因总结,用户们可以看看

这是一篇关于沃尔沃挖机的常见故障及可能原因的总结送给大家 &#xff0c;希望能对沃尔沃挖机使用者提供一定的参考借鉴。一、沃尔沃210型挖机热车难启动故障现象&#xff1a;用户平时经常遇到冷车好启动、热车要打好几次才能启动。原因&#xff1a;1.可能是油泵有问题&#xf…

讲座感悟

我于周四、周五上午十点至十二点在山东大学齐鲁软件园校区圆形报告厅聆听了由Prof.Foley主持的精彩讲说&#xff0c;观看了Prof.Foley的最新研究成果以及对Computer Graphics的独到见解&#xff0c;我有如下的体会。 第一&#xff1a;计算机图形学的目标是实现与真实世界的完美…

计算机在材料中的运用结课,计算机在材料科学工程中的应用的结课论文.doc

计算机在材料科学工程中的应用的结课论文《计算机在材料科学与工程中的应用》的结课论文做为一个21世纪的大学生&#xff0c;计算机就显得尤为重要&#xff0c;而我们的本专业是21世纪的新型专业材料科学与工程&#xff0c;那么学好二者就更为重要&#xff0c;在大三我们学校给…

C#生成DLL文件

使用csc命令将.cs文件编译成.dll的过程 很多时候,我们需要将.cs文件单独编译成.dll文件, 操作如下: 打开命令窗口->输入cmd到控制台->cd C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322 转到vs.net安装的该目录下->执行csc命令csc /target:library File.cs->在该目…

通过live555实现H264 RTSP直播

前面的文章中介绍了《H264视频通过RTMP流直播》&#xff0c;下面将介绍一下如何将H264实时视频通过RTSP直播。 实现思路是将视频流发送给live555, 由live555来实现H264数据流直播。 视频采集模块通过FIFO队列将H264数据帧发送给live555. live555 在收到客户端的RTSP播放请求后&…

计算机网络设置端口转发,网件NETGEAR几款路由器端口转发功能设置方法

WPN824, RP614v2&#xff0c;MR814v2&#xff0c;WGR614&#xff0c;WGT624 端口转发设置实例。(以 RP614v2 为例)1. WPN824, RP614v2&#xff0c;MR814v2&#xff0c;WGR614&#xff0c;WGT624 如何设置端口转发&#xff1f; 先登陆到设备的配置截面 在‘高级选项(Advanced)’…

计算机分数的简便运算,分数的简便运算和分数的解方程

问题描述&#xff1a;分数的简便运算和分数的解方程简便运算四又十五分之八一又二十分之十三三又四分之一十-二又十二分之七-四又六分之五五又五分之二-(1.8二又四分之九)二又三分之一-1.5三又十二分之五六又十三分之五-2.375-一又八分之五3.825二又九分之四一又九分之五四又三…

OpenGL 4.0 Tutorials 第三章:初始化 OpenGL 4.0

原文地址&#xff1a; http://www.rastertek.com/gl40tut03.html Tutorial 3: Initializing OpenGL 4.0 第三章&#xff1a;初始化 OpenGL 4.0 This tutorial will be the first real introduction to working with OpenGL 4.0. We will address three main things which are …

客户机和服务器在s7通信中各有什么作用,哪些通信口可以进行 Modbus TCP 通讯,作为 Modbus 服务器的 SIMATIC S7 CPU 可以...

以下通信端口可用于 Modbus/TCP 协议&#xff1a;在默认情况下&#xff0c;端口号 502 作为 Modbus 服务器的本地端口。可以在 Modbus 客户机中设置需要的本地端口&#xff0c;通常使用从 2000 开始的端口号。如果通信伙伴具有为服务器设置端口号的功能&#xff0c;那么也可以使…

移位操作符

移位操作符操作运算对象是 位(bit) 它处理的数据类型只能是 整数类型(int) 先大概看一下图,了解它是怎么移动的,下面会解释规则 移位的时候关注两点, 1.移动的方向 2.空缺位置的填补形式. "有符号"左移位操作符(<<) 将二进制数据左移(在低位补0). int i 124…

【OpenGL】详解第一个OpenGL程序

写在前面 OpenGL能做的事情太多了&#xff01;很多程序也看起来很复杂。很多人感觉OpenGL晦涩难懂&#xff0c;原因大多是被OpenGL里面各种语句搞得头大&#xff0c;一会gen一下&#xff0c;一会bind一下&#xff0c;一会又active一下。搞到最后都不知道自己在干嘛&#xff0c;…