2016-02-29 15 views
18

Jaki jest cel deklaracji typów wyliczeniowych? Czy to zaraz po nazwie wyliczenia? I widział standard C++ 14 (n4296) §3.3.2/3:Punkt deklaracji dla wyliczenia

Punkt zgłoszenia na wyliczenie jest natychmiast po identyfikatorze (jeśli występuje) albo w jego wyliczeniowego-specyfikacją (7.2) lub jego pierwszy Deklaracja opaque-enum (7.2), w zależności od tego, co nastąpi wcześniej:

Ale kiedy próbuję ją odtworzyć;

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

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

Mam błąd na wszystkich kompilatorów, chociaż enum-base dla wyliczenia E umieszczony za identyfikatorem i muszą być widoczne.

+1

Powiedziałbym, że jest w ';' (przed '// error') deklaracji * opaque-enum *. – Jarod42

+1

Tak więc w 'CL ', 'E' nie jest jeszcze zadeklarowana :( – Jarod42

+1

Jarod42, ale dlaczego nie jest jeszcze zadeklarowana? Standard mówi, że jest zaraz po identyfikatorze, czyż nie? Nie rozumiem it – user3514538

Odpowiedz

13

Następujące;

Nie jest akceptowana jako poprawna deklaracja w niektórych bieżących implementacjach (testowany kod ++, g ++ i MSVC). Nie akceptują one jeszcze niekompletnego typu E, w enum-base enum-base . Błąd podany w testowanych implementacjach jest taki, że E jest niezadeklarowany w tym punkcie. Wydaje się, że umieszczają punkt deklaracji na końcu enum-enum-base, uznają go za zadeklarowany, gdy jest kompletny.

Podczas czytania specyfikacji;

§14.3.1/2 Typ szablonu argumenty

[Uwaga: typ argumentu szablon może być niepełne rodzaju (3,9). - koniec Uwaga]

I

§7.2/6 zgłoszeń Wyliczenie

Wyliczenie którego Bazowy typ stałej jest niekompletny typu z punktu zgłoszenia (3.3.2) do zaraz po swojej enum-base (jeśli istnieje), w którym to momencie staje się pełnym typem.

Wskazuje na to, że jest on kompilowany; tak jak w przypadku implementacji CRTP.

Jestem pewien, że jeśli to (tj. Brak kompilacji enum class E : CL<E>::UndType;) jest intencją lub jeśli zostało to uznane za przypadek użycia. Ze specyfikacji wynika, że ​​deklaracja "enum" jest opatrzona pewnym "specjalnym" traktowaniem w.r.t. jego typ podstawowy i wymóg, że musi to być typ integralny.

Przypuszczalnie kod powinien być kompilowany, z uwzględnieniem rozdzielczości na CWG#1482.


Co do bieżących obejść ...

To;

enum class E; // default underlying type is int 

Jest deklaracją minimalną.

Nieprzejrzysta deklaracja może być;

enum class E : int; // int base 

Poniżej znajduje się pełna definicja (w tym moduły wyliczające);

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

Lub użyć szablonu klasy, można użyć innego typu (prawdopodobnie void).

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

Od http: // en.cppreference.com/w/cpp/language/enum, rodzaj bazowy jest częścią deklaracji. 'enum class E' jest po prostu równoznaczne z' enum class E: int'. A zmiana 'UndType' na' char' powoduje nawet błąd [Demo] (http://coliru.stacked-crooked.com/a/1b7463cc118c5fd6). – Jarod42

+1

Teraz jest lepiej, ale część dotycząca * enum-base * jest "jeszcze nie ukończona" nadal nie jest właściwa. Jest to alias do 'int', to wszystko; fakt, że 'E' jest rzeczywiście niekompletny, gdy' CL 'jest pośrednio utworzony, jest w tym przypadku nieistotny. – bogdan

+1

@bogdan. Prawidłowo, myślę, że to jest sedno sprawy, implementacje nie uznają jej za kompletną - myślę, że muszę jakoś przeformułować tę część. Może coś w stylu "Nie akceptują, jeszcze niekompletnego typu" E "w bazie' CL :: UndType'. "? – Niall

Powiązane problemy