2013-07-23 12 views
7

Nel seguente codice, il sovraccarico f(int) viene scelto al posto di f(unsigned). Testato con clang 3.0 e gcc 4.8.Cosa rende enum -> int una conversione migliore di enum -> unsigned?

enum E 
{ 
}; 

E f(int); 
int f(unsigned); 

E e = f(E(0)); 

La mia lettura della norma mi portano a pensare che enum -> int e enum -> unsigned sono identiche sequenze di conversione standard che entrambi contengono solo un integrale conversione.

[conv.integral] Un valore di un tipo di enumerazione può essere convertito in un valore di un tipo intero.

Secondo [over.best.ics], il rango di una sequenza di conversione standard contenente solo una conversione integrale è "Conversione".

[over.ics.rank] Due sequenze conversione implicita della stessa forma sono sequenze di conversione indistinguibili se non applicare una delle seguenti regole: [...]

Nessuna delle norme citate sembrano da applicare quando si confrontano le due sequenze di conversione standard.

Cosa mi manca?

+0

'enum' ha un' int' sottostante di default, quindi sospetto sia per questo che la conversione sia migliore. Se dite di usare un 'short' o' char', scommetto che otterrete l'ambiguità che vi aspettate. –

+0

Devi usare ['std :: underlying_type'] (http://en.cppreference.com/w/cpp/types/underlying_type) per capire il tipo sottostante dell'enum. –

+0

Promozione integrale. In realtà non è una conversione integrale; vedere [conv.prom] – dyp

risposta

6

C++ 11:

[conv.prom]/3

Una prvalue di un tipo di enumerazione senza ambito cui sottostante tipo non è fisso (7,2) possono essere convertiti in un prvalue della primo dei seguenti tipi che può rappresentare tutti i valori del conteggio (cioè i valori nell'intervallo b min a max b come descritto in 7.2): int, unsigned int, long int, unsigned long int, long long int o unsigned long long int.

(sottolineatura mia)

Poi, [over.ics.rank]/4:

sequenze di conversione standard sono ordinate per loro ranghi: una corrispondenza esatta è una conversione di meglio di una Promozione, che è una conversione migliore di una conversione.

Così, per la risoluzione di sovraccarico sull'espressione f(E(0)), il sovraccarico E f(int); richiede solo una promozione integrale (da E a int, tramite [conv.prom]), che ha un rango superiore la conversione integrale richiesto per int f(unsigned); (da E a unsigned tramite [conv.integral]).


Per C++ 03, l'argomentazione è la stessa, se la prima citazione è leggermente diversa: [conv.prom]/2

Un rvalue di tipo wchar_t (3.9.1) o un tipo di enumerazione (7.2) può essere convertito in un rvalue del primo dei seguenti tipi che può rappresentare tutti i valori del suo tipo sottostante: int, unsigned int, long o unsigned long.

[over.ics.rank]/4 è lo stesso.

+0

mi serve correttamente per riferirsi a C++ 03! – willj

+0

fanno in modo che "mi serva per scremare C++ 03";) – willj

+0

@willj Da quello che so, la promozione integrale non è una caratteristica ampiamente nota. – dyp

Problemi correlati