为什么要编译无作用域枚举的声明?
Why unscoped enums' declaration compiles?
在Effective Modern C++
Scott Meyers的书中,提到,未达到和范围的枚举(Enum class)之间的主要区别之一是我们无法转发前者(请参阅第3章,项目10- "更喜欢范围的枚举,而不是未指示的枚举" )。例如:
enum Color; *// error!*
enum class Color; *// fine*
,但我在下面写了一个小例子,发现事实并非如此。
test.h
#pragma once
enum names;
void print(names n);
test.cpp
#include "test.h"
#include <iostream>
enum names { John, Bob, David };
void print(names n)
{
switch (n)
{
case John:
case Bob:
case David:
std::cout << "First names." << std::endl;
break;
default:
std::cout << "Other things" << std::endl;
};
}
main.cpp
#include "test.h"
#include <iostream>
int main()
{
names n = static_cast<names>(2);
print(n);
return 0;
}
我已经使用了VC14编译器(Visual Studio 2015)。这是编译器的错误还是功能?还有其他吗?如果这是错误或功能(考虑到Meyers说这是未达到和范围的枚举之间的主要区别),则意味着编译器能够管理我们可以宣布无人枚举的情况。因此,是否需要在枚举之后添加新的关键字class
?当然,有人会说还有其他两个范围的枚举特征。正如我所得到的,上述功能是最重要的。
c 11
首先:C 11确实允许向前声明未指示的枚举。您只需要将基础类型提供给编译器(例如有效的现代C ,第3章,项目10):
enum Color: std::uint8_t;
您使用的是编译器的非标准扩展,但无论如何它都可能。
重要或不重要
斯科特·迈耶斯(Scott Meyers)在引用的章节中说:
范围似乎比未占用的枚举具有第三个优势枚举,因为范围的枚举可能是向前宣布的,即他们的名字可以在不指定其枚举者的情况下声明:[...] 在C 11,未指示的枚举也可能是向前宣布的,但只有在一些其他工作。
'可能看起来指" IS"的对立面。斯科特·迈耶斯(Scott Meyers)本人指出,这不是该书中的重要特征。
相关文章:
- 访问在 C++ 结构中声明的枚举变量
- 如何使用默认值将枚举声明为 extern
- 如何转发声明枚举?
- 如何将枚举类转发声明为模板化类的内部类?
- 枚举前向声明与头文件
- C++:如何在声明枚举类的模板类主体之外定义枚举类?
- 在C++代码中使用的 C 标头中向前声明枚举
- 在哪里声明枚举
- 在模板参数内向前声明枚举类
- 在C++14中,在哪个作用域中声明了重新声明枚举的非范围枚举器
- 在C中定义的C++中正向声明枚举
- 在不膨胀命名空间的情况下在C++中声明枚举的好方法
- 声明枚举标识符的基础类型
- 为什么在向前声明枚举时必须提供枚举的大小?
- 前向声明枚举类不起作用
- 在运行时有条件地声明枚举(C++)
- 我可以传递前向声明枚举的值吗?
- c++ -对声明枚举感到困惑
- c++:在类内部从外部声明枚举器,以便可以在私有成员中使用
- 在声明枚举之前使用它