【发布时间】:2017-09-23 12:28:26
【问题描述】:
在 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?当然,有人会说作用域枚举还有另外两个特点。据我了解,上述功能是最重要的。
【问题讨论】:
-
这在 Visual Studio 2017 中无法编译 - 所以听起来它要么是编译器错误,要么是编译器特定的扩展
-
这是 MSVC 编译器的一个缺陷。它甚至可以使用
/permissive-成功编译,这会强制 MSVC 进入一致性模式。 -
@UnholySheep 您使用的是什么 MSVC 版本?对我来说,它在 19.11.25508.2 和 19.11.25545 上都使用
/permissive-成功编译。 -
@tambre 我正在使用 MSVC 19.11.25506,即使没有
/permissive-,我也会收到错误“C3432 'names':无作用域枚举的前向声明必须具有基础类型” -
@tambre 我尝试升级到 MSVC 19.11.25508.2,但我仍然收到与以前相同的错误 - 编辑:我的项目在设置中有
/Za(禁用语言扩展) - 删除它确实允许这样做编译代码