为什么无范围的枚举声明编译?

时间:2017-09-23 12:28:27

标签: c++ c++11 enums

在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枚举还有其他两个功能。我得到它,上面提到的功能是最重要的。

1 个答案:

答案 0 :(得分:4)

C ++ 11

首先:C ++ 11允许前向声明未作用域的枚举。您只需将基础类型提供给编译器(例如Effective Modern C ++,第3章,第10项):

enum Color: std::uint8_t;

您使用的是编译器的非标准扩展,但无论如何都是可能的。

重要与否

斯科特迈耶斯在引用的章节中说:

  

似乎范围内的枚举比没有范围的枚举具有第三个优势   枚举,因为作用域的枚举可以是前向声明的,即它们的名称   可以在不指定其枚举器的情况下声明:   [...]在...   C ++ 11,未编译的枚举也可以是前向声明的,但只能在a之后   一点额外的工作。

“可能看起来”意味着“是”的反面。斯科特迈耶斯本人表示,这不是所述书中的一个重要特征。