2016-02-29 134 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