C++ 的枚举 enum

C++ 的枚举 enum,用来在有限的范围定义明确命名的常量,通常值是整数类型。每个枚举项都与一个底层类型常量值对应,如果未指明,第一项为 0,其他项均为前一项 +1。

enum Color {
	blue, // 0
	green, // 1
	red = 6,
	gray, // 7
};

有两种风格的枚举型别,C++98 风格的枚举型别和 C++11 风格的型别,两者有很大区别,通常来说后者更有优势。
C++98:

enum Color {
}

C++11:

enum class Color {
}
  • 前者的枚举量的访问范围不只在枚举型别中,包含该枚举类型的地方都被包括,被称为不限范围的枚举型别;后者加了 class,是限定范围的枚举型别,也被称为枚举类。
  • 不限范围枚举型别的枚举量会隐式转换到整数型别,从而可以转换到浮点型别。限定范围的枚举型别则不会隐式转换,如果需要采用强制转换的方式。
  • 两者在 C++11 中都可以进行前置声明,但是前者需要编译器选择一个整数型别作为其底层型别,通常会为枚举型别采用足够表示枚举量值的最小底层型别(有时编译器会用空间换时间,这意味着可能不会采用足够表示的最小底层类型)。限定作用域的枚举型别的底层型别是已知的,而不限定作用域的枚举型别是供指定的。
  • 底层型别的指定可以在枚举型别声明和定义中指定,限定作用域的底层型别默认是 int
#include 
 
using namespace std;

enum class Color;
//  {
// 	blue,
// 	green,
// 	red = 6,
// 	gray,
// };

int main(int argc, char* argv[]) {
	 bool is_int_type = std::is_same<int, 
	 	typename std::underlying_type<Color>::type>::value;
	if (is_int_type) {
		std::cout << "int type\n";
	}
	return 0;
}

不管限定作用域与否,都可以使用“:”指定方式指定底层型别:

enum class Color: long long;
  • 当引用 C++11 中的 std::tuple 型别的各个作用域时,前者比较适用。
    对于单纯的 tuple 在外部不便得知每一项的信息,
#include 
#include 

using namespace std;

// enum class Color {
// 	blue,
// 	green,
// 	red = 6,
// 	gray,
// };

int main(int argc, char* argv[]) {
	using Color = std::tuple<char, int, double>;
	Color color{'a', 6, 2.33f};
	auto b = std::get<2>(color);
	std::cout << b << "\n";
	return 0;
}

而采用不限范围的枚举型别则比较适合

#include 
#include 

using namespace std;

enum ColorInfo {
	b,
	g,
	r,
};

int main(int argc, char* argv[]) {
	using Color = std::tuple<char, int, double>;
	Color color{'a', 6, 2.33f};
	auto b = std::get<r>(color);
	std::cout << b << "\n";
	return 0;
}

参考:
Effective Modern C++ 简体中文版

你可能感兴趣的:(C/C++)