为什么要编译无作用域枚举的声明?

Why unscoped enums' declaration compiles?

本文关键字:声明 枚举 作用域 编译 为什么      更新时间:2023-10-16

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)本人指出,这不是该书中的重要特征。