枚举类型(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

C++11中enum class的使用相关推荐

  1. C++11中头文件type_traits介绍

    C++11中的头文件type_traits定义了一系列模板类,在编译期获得某一参数.某一变量.某一个类等等类型信息,主要做静态检查. 此头文件包含三部分: (1).Helper类:帮助创建编译时常量的 ...

  2. C++11中std::async的使用

    C++11中的std::async是个模板函数.std::async异步调用函数,在某个时候以Args作为参数(可变长参数)调用Fn,无需等待Fn执行完成就可返回,返回结果是个std::future对 ...

  3. php定义枚举,PHP中Enum(枚举)用法实例详解

    本文实例讲述了PHP中Enum(枚举)用法.分享给大家供大家参考,具体如下: PHP其实有Enum类库的,需要安装perl扩展,所以不是php的标准扩展,因此代码的实现需要运行的php环境支持. (1 ...

  4. java中enum类型的使用

    java 枚举类型enum 的使用 最近跟同事讨论问题的时候,突然同事提到我们为什么java 中定义的常量值不采用enmu 枚举类型,而采用public final static 类型来定义呢?以前我 ...

  5. C++11中的一些新特性以及代码详解

    C++11新特性 auto decltype 追踪返回类型 类内成员初始化 列表初始化 基于范围的for循环 静态断言 noexcept修饰符 强类型枚举 常量表达式 原生字符串字面值 继承控制 fi ...

  6. linux下enum类型占几个字节,第11课 - enum, sizeof, typedef 分析

    第11课 - enum, sizeof, typedef 分析 1. enum介绍 (1)enum是C语言中的一种自定义类型,和struct.union地位相同,格式如下: // enum每个值的最后 ...

  7. C++11中std::packaged_task的使用

    C++11中的std::packaged_task是个模板类.std::packaged_task包装任何可调用目标(函数.lambda表达式.bind表达式.函数对象)以便它可以被异步调用.它的返回 ...

  8. C++11中std::shared_future的使用

    C++11中的std::shared_future是个模板类.与std::future类似,std::shared_future提供了一种访问异步操作结果的机制:不同于std::future,std: ...

  9. C++11中std::future的使用

    C++11中的std::future是一个模板类.std::future提供了一种用于访问异步操作结果的机制.std::future所引用的共享状态不能与任何其它异步返回的对象共享(与std::sha ...

最新文章

  1. SEO优化可以从这几个方面着手
  2. APP多版本共存,服务端如何兼容?
  3. _D类、E类、F类冷藏车是什么意思?
  4. HDU-1269 Tarjan求强连通分量,模板题
  5. 《图解服务器网络架构》 学习笔记
  6. 庖丁解牛-----Live555源码彻底解密(根据MediaServer讲解Rtsp的建立过程)
  7. win10上面安装win7的虚拟机怎么相互ping通
  8. JQuery 之 跳出循环
  9. 95-38-150-Buffer-CompositeByteBuf
  10. 基于guava的重试组件Guava-Retryer
  11. 如何不用电脑安装ipa
  12. 稳压二极管及特性介绍
  13. LAYA_展示富文本
  14. 2020-09-07(基于控制台的DVD管理系统)
  15. 关于写作,别那么在意别人的看法,开始干吧
  16. SQL Server安全(4/11):许可(Permissions)
  17. linux如何彻底删除mysql_Linux下如何彻底删除MySQL
  18. XMLHttpRequest cannot load的解决方法
  19. 关于SNS社区与行业电子商务结合一些看法
  20. 示波器和万用表测量直流电压的区别

热门文章

  1. 基于语义分割的视频弹幕防挡实现(训练、测试、部署实现)
  2. python显示行数_在idle中如何显示行号
  3. 基于Sobel计算图像梯度图
  4. qdockwidget设置隐藏标题栏,重叠时tab标签位置,自动填充满整个窗口
  5. 第二十五章 面向对象------封装、内置函数、反射、动态导入
  6. python_2开发简单爬虫
  7. Python学习心得第一周-03练习2
  8. getURLParameters - 网址参数
  9. git---远程仓库版本回滚
  10. event.keyCode用法及列表