2013-03-31 10 views
10

una citazione da C++ 11 (17.5.2.1.2 tipi enumerati) standard:C++ 11 "tipi enumerati" (17.5.2.1.2)

1 Diversi tipi definiti nella Clausola 27 sono tipi numerati. Ogni tipo enumerato può essere implementato come un'enumerazione o come sinonimo di un'enumerazione (come un tipo intero, con valori interi costanti (3.9.1)).

2 Il tipo enumerato enumerato può essere scritto:

enum enumerated { V0 , V1 , V2 , V3 , ..... }; 
static const enumerated C0 (V0); 
static const enumerated C1 (V1); 
static const enumerated C2 (V2); 
static const enumerated C3 (V3); 
..... 

3 Qui, i nomi C0, C1, ecc rappresentare elementi enumerati per questo particolare tipo enumerato. Tutti questi elementi hanno valori distinti.

Uno di questi "tipi enumerati" è "seekdir" dalla classe ios_base (27.5.3 Classe ios_base):

// 27.5.3.1.5 seekdir 
typedef T4 seekdir; 
static constexpr fmtflags beg = unspecified ; 
static constexpr fmtflags cur = unspecified ; 
static constexpr fmtflags end = unspecified ; 

e

27.5.3.1.5 Tipo ios_base: : seekdir [ios :: seekdir]

typedef T4 seekdir; 

1 Il tipo seekdir è un tipo enumerato (17.5.2.1.2) che contiene gli elementi indicati nella tabella 126.

Quindi, l'unico motivo sono richiesti i membri const e constexpr statici perché "tipi enumerati "possono essere implementati come tipo intero (es quando elencato è necessario definire costanti al posto di enumeratori), giusto?

Domanda 1. Se il fornitore di librerie decide di implementare seekdir come enumerazione deve ancora definire costanti statiche per i valori di enumerazione?

Domanda 2. PERCHE 'i "tipi enumerati" possono essere implementati come tipi interi in primo luogo? Cioè quando l'implementazione di enum (e nelle enumerazioni di C++ 11 può avere qualsiasi tipo di intero sottostante) senza quei membri statici costanti può essere peggiore dell'implementazione del tipo intero?

+1

Domanda bonus: perché si dice 'static constexpr fmtflags beg = non specificato;' nella sinossi di 'ios_base' invece di' static constexpr seekdir beg = unspecified; '? - L'ho appena segnalato ai ragazzi dello Standard, sembra un errore di battitura. –

+0

@Daniel "ha riferito questo ai ragazzi dello Standard" - cool, come si fa? :) Inoltre, TBH, anche dopo aver incollato la copia di quella citazione, non ho notato questo errore. – PowerGamer

+0

Ho scritto una mail all'indirizzo indicato sulla copertina dello Standard. Dovrebbe essere abbastanza buono per un errore così ovvio, immagino. In generale, dovresti seguire [queste linee guida] (http://isocpp.org/std/submit-a-library-issue). –

risposta

3

Il motivo originale per richiedere oggetti per i valori dei tipi enumerati era che si potesse prendere il loro indirizzo. Mi è sempre sembrato sciocco, ma nelle prime fasi della standardizzazione c'era un bel po 'di sovra-design.

+0

Divertente, l'ho avuto anche come parte della mia risposta e l'ho modificato perché non potevo per la sua vita pensare ad un esempio in cui potrebbe essere utile :) –

+0

@Pete Quindi consentire il tipo intero per "tipi enumerati" e richiedere i membri della classe const statica in C++ 11 è solo un altro caso di retrocompatibilità? E anche se un venditore decide di utilizzare per es. "enum seekdir: int" avrebbe ancora bisogno di definire quei membri statici di constexpr? – PowerGamer

+0

@PowerGamer, sì, lo standard richiede un'implementazione per definire oggetti denominati con indirizzi, non può semplicemente definire enumeratori. –

6

Quando lo standard è stato scritto, enumerazioni fortemente tipizzato non erano disponibili e il problema con la pianura enum a dire, che il loro tipo interno non è specificato e può cambiamento seconda opzioni del compilatore.

Per seekdir, potrebbe essere int o byte (come un esempio), entrambi sarebbero rappresentazioni valide. GCC ha un'opzione a riga di comando per quello (--short-enums o -fshort-enums), per impostazione predefinita utilizza per tutti gli enum s come il tipo più piccolo, ma con l'opzione utilizzerà il tipo più piccolo che potrebbe contenere tutti i valori.

Ciò significa che se un vero enum viene utilizzato in una firma di funzione, il simbolo potrebbe cambiare e sarà necessario ricompilare tutto. Questo è il motivo per cui lo standard consente altre opzioni, perché è importante che l'implementazione della libreria standard abbia il controllo sul tipo e questo è il motivo per cui è consentito ricorrere a tipi interi specifici.

+0

+1, ben fatto

+0

@Daniel Stai implicando che indietro nel giorno (prima di C++ 11) Le implementazioni di libreria standard in GCC utilizzavano il tipo intero invece di enum per seekdir a causa del problema che descrivi? – PowerGamer

+0

@PowerGamer, nel caso specifico di GCC, no, 'seekdir' è stato un typedef per' enum _Ios_Seekdir' finchè posso ricordare –