2014-11-04 11 views
9

Ho una domanda sulla formulazione dello standard C++ 11 in quanto non ho dovuto scavare frequentemente in passato e di recente mi sono trovato confuso su (ovviamente poco importante) argomento di enumerazioni senza ambito.C++ 11 Accesso agli enumeratori senza ambito con nome qualificato

Recentemente ho sono imbattuto in un codice in una revisione del codice che stava usando un enum senza ambito, ma l'accesso alle enumeratori utilizzando nomi completi, in questo modo:

enum SomeEnum 
{ 
    EnumA, 
    ... 
}; 

void foo() 
{ 
    SomeEnum x = SomeEnum::EnumA; 
} 

ero certo che questo non ha funzionato e che SomeEnum doveva essere una classe di enum per questo comportamento, ma, abbastanza sicuro, compilato in modo pulito.

Sbirciare nello standard C++ 11, ho pensato in un primo momento che lo standard d'accordo con me:

§ 7.2 Dichiarazioni Enumeration: Ogni enum-nome e ciascuna senza ambito enumeratore è dichiarata nel ambito che contiene immediatamente l'identificatore enum . Ogni enumeratore con ambito è dichiarato nell'ambito dell'enumerazione .

Questo mi sembra indicare che gli enumeratori non disposti sono dichiarati solo nello spazio immediatamente contenuto dell'enum stesso. Non menziona che sono anche dichiarati nell'ambito di enumerazione.

Tuttavia, un po 'più in basso, lo standard include un esempio che mostra l'accesso a un enumeratore non spopolato utilizzando il nome completo.

Un rapido bit di ricerca su google e su SO mi ha dato un piccolo numero di punti che affermano che lo standard ora consente il nome completo, ma non c'è molta discussione. Si tratta solo di una formulazione debole nella specifica che viene chiarita dall'esempio, o c'è qualcos'altro che mi manca?

Ancora una volta, questo non è sconvolgente, ma spero che qualcuno possa mettermi sulla mia lettura dello standard e posso imparare qualcosa che potrebbe essere utile in una situazione futura.

risposta

7

La citazione che stai cercando dal draft C++11 standard è dalla sezione 5.1espressioni primarie cui al paragrafo dice:

A nested-nome-identificatore che denota un'enumerazione (7.2), seguita di il nome di un enumeratore di tale enumerazione, è un id qualificato che fa riferimento all'enumeratore. Il risultato è l'enumeratore. Il tipo di il risultato è il tipo dell'enumerazione. Il risultato è un valore.

Esso non limita l'utilizzo di ambito enumerazioni e così l'esempio nella sezione 7.2dichiarazioni Enumeration:

enum direction { left='l', right='r' }; 

void g() { 
    direction d; // OK 
    d = left; // OK 
    d = direction::right; // OK 
} 

è del tutto coerente.Questo è anche coerente con la sezione 3.4.3qualificata ricerca del nome che dice:

Il nome di un membro di classe o spazio dei nomi o enumeratore può essere riferito al dopo il :: operatore di risoluzione dell'ambito (5.1) applicato ad un nested-name-specificatore che denota la sua classe, namespace o enumerazione . [...]

e:

Un nome preceduto da una nested-nome-identificatore che nomina un tipo di enumerazione rappresenterà un enumeratore di quella enumerazione.

di nuovo, non c'è nulla che limiti questo comportamento alle enumerazioni con scope.

Examples are non normative ma fintanto che non sono in conflitto con il testo normativo, allora dovrebbero essere considerati una buona linea guida.

+0

Oppure, per semplificare, la domanda è completamente corretta su quali nomi sono dichiarati in quale ambito, è solo che esiste un'eccezione speciale per '::' dove 'A :: B' non cerca' B 'nell'ambito di' A'. – hvd

+1

Mi ricordo in C++ 03, che gli enumeratori completamente qualificati hanno provocato un errore del compilatore. C++ 11 ha apportato una modifica per consentire agli enumeratori unscoped completamente qualificati? O era sempre permesso, ma i compilatori (guardando a MSVC) erano bacati/non conformi? –

+0

@ void.pointer Vorrei solo usare Wandbox o Coliru e usare la flag '-pedantic' con gcc o clang, possiamo vedere [in questo esempio] (http://melpon.org/wandbox/permlink/WbjqktMcxle9UXk0) clang dice che è un'estensione C++ 11 in C++ 03. Sembra che [N2347] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2347.pdf) abbia aggiunto la dicitura. –

Problemi correlati