当前位置: 首页 > 编程日记 > 正文

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_

GitHub: https://github.com/fengbingchun/Messy_Test

相关文章:

Windows下Mysql主从配置(Mysql5.5)

主数据库IP:192.168.3.169从数据库IP:192.168.3.34主数据库配置my.inin&#xff1a;在[mysqld]下添加配置数据&#xff1a;server-id1 #配一个唯一的ID编号&#xff0c;1至32。log-binmysql-bin #二进制文件存放路径#设置要进行或不要进行主从复制的数据库名&#xff0c;同…

K-最近邻法(KNN) C++实现

关于KNN的介绍可以参考&#xff1a; http://blog.csdn.net/fengbingchun/article/details/78464169 这里给出KNN的C实现&#xff0c;用于分类。训练数据和测试数据均来自MNIST&#xff0c;关于MNIST的介绍可以参考&#xff1a; http://blog.csdn.net/fengbingchun/article/deta…

AI大佬“互怼”:Bengio和Gary Marcus隔空对谈深度学习发展现状

编译 | AI科技大本营编辑部出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;去年以来&#xff0c;由于纽约大学教授 Gary Marcus 对深度学习批评&#xff0c;导致他在社交媒体上与许多知名的 AI 研究人员如 Facebook 首席 AI 科学家 Yann LeCun 进行了一场论战。不止 …

Centos7多内核情况下修改默认启动内核方法

1.1 进入grub.cfg配置文件存放目录/boot/grub2/并备份grub.cfg配置文件 [rootlinux-node1 ~]# cd /boot/grub2/ [rootlinux-node1 grub2]# cp -p grub.cfg grub.cfg.bak [rootlinux-node1 grub2]# ls -ld grub.cfg* -rw-r--r--. 1 root root 5162 Aug 11 2018 grub.cfg -rw-r…

TensorRT Samples: MNIST

关于TensorRT的介绍可以参考&#xff1a; http://blog.csdn.net/fengbingchun/article/details/78469551以下是参考TensorRT 2.1.2中的sampleMNIST.cpp文件改写的实现对手写数字0-9识别的测试代码&#xff0c;各个文件内容如下&#xff1a;common.hpp:#ifndef FBC_TENSORRT_TE…

网红“AI大佬”被爆论文剽窃,Jeff Dean都看不下去了

作者 | 夕颜、Just出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;【导读】近日&#xff0c;推特上一篇揭露 YouTube 网红老师 Siraj Raval 新发表论文涉抄袭其他学者的帖子引起了讨论。揭露者是曼彻斯特大学计算机科学系研究员 Andrew M. Webb&#xff0c;他在 Twit…

数位dp(求1-n中数字1出现的个数)

题意&#xff1a;求1-n的n个数字中1出现的个数。 解法:数位dp&#xff0c;dp[pre][now][equa] 记录着第pre位为now&#xff0c;equa表示前边是否有降数字&#xff08;即后边可不能够任意取&#xff0c;true为没降&#xff0c;true为已降&#xff09;&#xff1b;常规的记忆化搜…

TensorRT Samples: MNIST API

关于TensorRT的介绍可以参考&#xff1a; http://blog.csdn.net/fengbingchun/article/details/78469551 以下是参考TensorRT 2.1.2中的sampleMNISTAPI.cpp文件改写的实现对手写数字0-9识别的测试代码&#xff0c;各个文件内容如下&#xff1a;common.hpp:#ifndef FBC_TENSORR…

免费学习AI公开课:打卡、冲击排行榜,还有福利领取

CSDN 技术公开课 Plus--AI公开课再度升级内容全新策划&#xff1a;贴近开发者&#xff0c;更多样、更落地形式多样升级&#xff1a;线上线下、打卡学习&#xff0c;资料福利&#xff0c;共同交流成长&#xff0c;扫描下方小助手二维码&#xff0c;回复&#xff1a;公开课&#…

Gamma阶段第一次scrum meeting

每日任务内容 队员昨日完成任务明日要完成的任务张圆宁#91 用户体验与优化&#xff1a;发现用户体验细节问题https://github.com/rRetr0Git/rateMyCourse/issues/91#91 用户体验与优化&#xff1a;发现并优化用户体验&#xff0c;修复问题https://github.com/rRetr0Git/rateMyC…

windows 切换 默认 jdk 版本

set JAVA_HOMEC:\jdk1.6.0u24 set PATH%JAVA_HOME%\bin;%PATH%转载于:https://www.cnblogs.com/dmdj/p/3756887.html

TensorRT Samples: GoogleNet

关于TensorRT的介绍可以参考&#xff1a; http://blog.csdn.net/fengbingchun/article/details/78469551 以下是参考TensorRT 2.1.2中的sampleGoogleNet.cpp文件改写的测试代码&#xff0c;文件(googlenet.cpp)内容如下&#xff1a;#include <iostream> #include <t…

Visual Studio Code Go 插件文档翻译

此插件为 Go 语言在 VS Code 中开发提供了多种语言支持。 阅读版本变更日志了解此插件过去几个版本的更改内容。 1. 语言功能 (Language Features) 1.1 智能感知 (IntelliSense) 编码时符号自动补全&#xff08;使用 gocode &#xff09;编码时函数签名帮助提示&#xff08;使用…

资源 | 吴恩达《机器学习训练秘籍》中文版58章节完整开源

整理 | Jane出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;一年前&#xff0c;吴恩达老师的《Machine Learning Yearning》(机器学习训练秘籍&#xff09;中文版正式发布&#xff0c;经过一年多的陆续更新&#xff0c;近日&#xff0c;这本书的中文版 58…

js字符串加密的几种方法

在做web前端的时候免不了要用javascript来处理一些简单操作&#xff0c;其实如果要用好JQuery, Prototype,Dojo 等其中一两个javascript框架并不简单&#xff0c;它提高你的web交互和用户体验&#xff0c;从而能使你的web前端有非一样的感觉&#xff0c;如海阔凭鱼跃。当然&…

Vue开发入门看这篇文章就够了

摘要&#xff1a; 很多值得了解的细节。 原文&#xff1a;Vue开发看这篇文章就够了作者&#xff1a;RandomFundebug经授权转载&#xff0c;版权归原作者所有。 介绍 Vue 中文网Vue githubVue.js 是一套构建用户界面(UI)的渐进式JavaScript框架库和框架的区别 我们所说的前端框架…

TensorRT Samples: CharRNN

关于TensorRT的介绍可以参考&#xff1a; http://blog.csdn.net/fengbingchun/article/details/78469551 以下是参考TensorRT 2.1.2中的sampleCharRNN.cpp文件改写的测试代码&#xff0c;文件(charrnn.cpp)内容如下&#xff1a;#include <assert.h> #include <str…

Python脚本BUG引发学界震动,影响有多大?

作者 | beyondma编辑 | Jane来源 | CSDN博客近日一篇“A guide to small-molecule structure assignment through computation of (1H and 13C) NMR chemical shifts”文章火爆网络&#xff0c;据作者看到的资料上看这篇论文自身的结果没有什么问题&#xff0c;但是&#xff0c…

C++中public、protect和private用法区别

Calsspig : public animal,意思是外部代码可以随意访问 Classpig : protect animal ,意思是外部代码无法通过该子类访问基类中的public Classpig : private animal ,意思是告诉编译器从基类继承的每一个成员都当成private,即只有这个子类可以访问 转载于:https://blog.51cto.…

TensorRT Samples: MNIST(Plugin, add a custom layer)

关于TensorRT的介绍可以参考&#xff1a;http://blog.csdn.net/fengbingchun/article/details/78469551 以下是参考TensorRT 2.1.2中的samplePlugin.cpp文件改写的通过IPlugin添加一个全连接层实现对手写数字0-9识别的测试代码&#xff0c;plugin.cpp文件内容如下&#xff1a…

AutoML很火,过度吹捧的结果?

作者 | Denis Vorotyntsev译者 | Shawnice编辑 | Jane出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;【导语】现在&#xff0c;很多企业都很关注AutoML领域&#xff0c;很多开发者也开始接触和从事AutoML相关的研究与应用工作&#xff0c;作者也是&#…

tomcat6 配置web管理端访问权限

配置tomcat 管理端登陆 /apache-tomcat-6.0.35/conf/tomcat-users.xml 配置文件&#xff0c;使用时需要把注释去掉<!-- <!-- <role rolename"tomcat"/> <role rolename"role1"/> <user username"tomcat" password"…

@程序员:Python 3.8正式发布,重要新功能都在这里

整理 | Jane、夕颜出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09;【导读】最新版本的Python发布了&#xff01;今年夏天&#xff0c;Python 3.8发布beta版本&#xff0c;但在2019年10月14日&#xff0c;第一个正式版本已准备就绪。现在&#xff0c;我们都…

TensorRT Samples: MNIST(serialize TensorRT model)

关于TensorRT的介绍可以参考&#xff1a; http://blog.csdn.net/fengbingchun/article/details/78469551 这里实现在构建阶段将TensorRT model序列化存到本地文件&#xff0c;然后在部署阶段直接load TensorRT model序列化的文件进行推理&#xff0c;mnist_infer.cpp文件内容…

【mysql错误】用as别名 做where条件,报未知的列 1054 - Unknown column 'name111' in 'field list'...

需求&#xff1a;SELECT a AS b WHRER b1; //这样使用会报错&#xff0c;说b不存在。 因为mysql底层跑SQL语句时&#xff1a;where 后的筛选条件在先&#xff0c; as B的别名在后。所以机器看到where 后的别名是不认的&#xff0c;所以会报说B不存在。 这个b只是字段a查询结…

C++2年经验

网络 sql 基础算法 最多到图和树 常用的几种设计模式&#xff0c;5以内即可转载于:https://www.cnblogs.com/liujin2012/p/3766106.html

在Caffe中调用TensorRT提供的MNIST model

在TensorRT 2.1.2中提供了MNIST的model&#xff0c;这里拿来用Caffe的代码调用实现&#xff0c;原始的mnist_mean.binaryproto文件调整为了纯二进制文件mnist_tensorrt_mean.binary&#xff0c;测试结果与使用TensorRT调用(http://blog.csdn.net/fengbingchun/article/details/…

142页ICML会议强化学习笔记整理,值得细读

作者 | David Abel编辑 | DeepRL来源 | 深度强化学习实验室&#xff08;ID: Deep-RL&#xff09;ICML 是 International Conference on Machine Learning的缩写&#xff0c;即国际机器学习大会。ICML如今已发展为由国际机器学习学会&#xff08;IMLS&#xff09;主办的年度机器…

CF1148F - Foo Fighters

CF1148F - Foo Fighters 题意&#xff1a;你有n个物品&#xff0c;每个都有val和mask。 你要选择一个数s&#xff0c;如果一个物品的mask & s含有奇数个1&#xff0c;就把val变成-val。 求一个s使得val总和变号。 解&#xff1a;分步来做。发现那个奇数个1可以变成&#x…

html传參中?和amp;

<a href"MealServlet?typefindbyid&mid<%m1.getMealId()%> 在这句传參中&#xff1f;之后的代表要传递的參数当中有两个參数第一个为type第二个为mid假设是一个參数就不用加&假设是多个參数须要加上&来传递