2016-02-29 230 views
18

枚举类型声明的要点是什么?它是在一个枚举的名字后面吗?只见标准C++ 14(n4296)§3.3.2/ 3:枚举声明点

声明的用于枚举的点立即是 标识符之后(如果有的话)在任一其枚举说明符(7.2)或它的第一 opaque-enum-declaration(7.2),以先到者为准

但是当我尝试重现它时;

template <class T> 
struct CL 
{ 
    using UndType = int; 
}; 

enum class E: CL<E>::UndType; //error: E is undefined 

我有对所有的编译器的错误,虽然枚举基用于枚举E被放置在标识符之后,并且必须是可见的。

+1

我会说它是在* opaque-enum-declaration *的'('//错误之前)'。 – Jarod42

+1

因此,在'CL '中,'E'确实还没有被声明:( – Jarod42

+1

Jarod42,但是为什么它还没有被声明呢?标准说它紧跟在标识符后面,不是吗?我不明白它 – user3514538

回答

13

以下;

enum class E : CL<E>::UndType; 

在某些当前实现(测试的clang ++,g ++和MSVC)中不被接受为有效声明。他们不接受在enum-baseCL<E>::UndType中尚未完成的E。在测试的实现中给出的错误是E未声明的在那一点。他们似乎在enum-base的末尾声明了声明的位置,他们认为声明完成后就会声明它。

在阅读规格时;

§14.3.1/ 2的模板类型参数

[注:模板类型参数可以是一个不完整的类型(3.9)。 - 注完]

而且

§7.2/ 6枚举声明

枚举其基础类型是固定的是从其点声明的一个不完整的类型(3.3.2)在它的enum-base(如果有)之后立即变为完整类型。

暗示它是可编译的;就像CRTP实施的情况一样。

我很确定这个(即​​编译失败enum class E : CL<E>::UndType;)是用意还是它被认为是一个用例。从规范中,不透明枚举声明被给予一些“特殊”处理w.r.t.它的基本类型以及它必须是一个整体类型的要求。

假定分辨率为CWG#1482,代码应该可编译


至于目前的解决方法...

这个;

enum class E; // default underlying type is int 

是最小声明。

不透明的声明可以是;

enum class E : int; // int base 

以下将是一个完整定义(包括枚举数);

enum class E : int {/*...*/}; 

或者要使用类模板,可以使用另一种类型(可能为void)。

enum class E : CL<void>::UndType; 
+5

从http:// en。cppreference.com/w/cpp/language/enum,基础类型是声明的一部分。 'enum class E'就相当于'enum class E:int'。 将'UndType'改为'char'甚至会产生错误[Demo](http://coliru.stacked-crooked.com/a/1b7463cc118c5fd6)。 – Jarod42

+1

现在比较好,但关于* enum-base *的部分是“尚未完成”的部分仍然不正确。这是'int'的别名,就是这样;在'CL '隐式实例化时'E'确实不完整的事实在这种情况下是不相关的。 – bogdan

+1

@bogdan。正确的,我认为这是问题的关键,实现并不认为它是完整的 - 我想我需要以某种方式改写该部分。也许是这样的:“他们不接受在'CL :: UndType'中不完整的'E'类型。”? – Niall