在Scott Meyers的Effective Modern C++
一书中,提到了无范围和范围的枚举(枚举类)之间的主要区别之一是我们无法转发声明前者(见第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
?当然,有人会说scoped枚举还有其他两个功能。我得到它,上面提到的功能是最重要的。
答案 0 :(得分:4)
首先:C ++ 11允许前向声明未作用域的枚举。您只需将基础类型提供给编译器(例如Effective Modern C ++,第3章,第10项):
enum Color: std::uint8_t;
您使用的是编译器的非标准扩展,但无论如何都是可能的。
似乎范围内的枚举比没有范围的枚举具有第三个优势 枚举,因为作用域的枚举可以是前向声明的,即它们的名称 可以在不指定其枚举器的情况下声明: [...]在... C ++ 11,未编译的枚举也可以是前向声明的,但只能在a之后 一点额外的工作。
“可能看起来”意味着“是”的反面。斯科特迈耶斯本人表示,这不是所述书中的一个重要特征。