2010-01-27 10 views
8

al valore di inizializzare un oggetto di tipo T, si potrebbe fare qualcosa sulla falsariga di uno dei seguenti:esplicita Tipo conversione e Multiple Specifiers Tipo semplici

T x = T(); 
T x((T())); 

La mia domanda riguarda tipi specificati da una combinazione di semplice specificatori di tipo, ad esempio, unsigned int:

unsigned int x = unsigned int(); 
unsigned int x((unsigned int())); 

Visual C++ 2008 e Intel C++ Compiler 11.1 accettare sia di questi senza avvertimenti; Comeau 4.3.10.1b2 e g ++ 3.4.5 (che è, certamente, non particolarmente recente) no.

Secondo lo standard C++ (C++ 03 5.2.3/2, expr.type.conv):

L'espressione T(), dove T è un semplice tipo-specificatore (7.1.5.2) per un non-array tipo di oggetto completa o la (possibilmente cv-qualificato) void tipo, crea un rvalue del tipo specificato, che è di valore inizializzato

7.1.5.2 dice "semplici specificatori tipo sono , "e segue con un elenco che include unsigned e int.

Pertanto, dato che in 5.2.3/2, "semplice-type-specifier" è singolare, e unsigned e int sono due identificatori di tipo, sono gli esempi di cui sopra che l'uso unsigned int valido? (e, se è così, il follow-up è, non è corretto per Microsoft e Intel supportare tali espressioni?)

Questa domanda è più per curiosità che altro; per tutti i tipi specificati da una combinazione di più specificatori di tipo semplice, l'inizializzazione del valore equivale all'inizializzazione zero. (Questa domanda è stata richiesta da comments in response to this answer to a question about initialization).

+0

Come osi interrogarmi. : 3 Penso che l'espressione '(unsigned int)' nomini un tipo, comunque. – GManNickG

+0

@GMan: '(unsigned int)()' fallisce con gcc 3 e 4 e anche con VC8. 'Naturalmente funzionano le versioni typedef. –

+0

H m. :( – GManNickG

risposta

8

I posted this question to comp.lang.c++.moderated.

Daniel Krugler del comitato standard C++ d'accordo con l'interpretazione che unsigned int è una combinazione di semplici specificatori di tipo, e non è di per sé un tipo semplice identificatore.

Per quanto riguarda la didascalia di tabella 7 referenced by Jerry Coffin, Krugler dice:

Sono d'accordo che l'intestazione della tabella 7 (che è Tabella 9 nella più recente progetto N3000) è un po 'fuorviante, ma la precede testo in [dcl.type.simple]/2 sembra molto chiaro per me, quando dice:.

tabella 7 riassume le combinazioni valide di semplici-type-prescrittori e dei tipi che specificano"

(Mi scuso ci ho messo così tanto tempo per postare questo qui dal newsgroup; mi è completamente sfuggito di mente)

1

Hmm, a volte è necessario un typedef. Se non dice che è necessaria una diagnosi, non è corretto per loro supportare questo. Tuttavia, per la portabilità, è possibile utilizzare un typedef (uint16_t o uint64_t, anche se quelli non potrebbe essere di destra), o citare il typename con un modello:

iterator<void, unsigned long>::value_type(5) 

Questa si che è irragionevolmente verbose?

Modifica: Duh, o semplicemente 5ul. Questo lascia unsigned short, unsigned char e signed char come gli unici tipi che non è possibile costruire in modo esplicito.

+0

Preferirei avere: 'modello struct same_type {typedef T type;};', un po 'più semplice. – GManNickG

+0

Preferisco non averne nessuno; v). Ho solo provato a pensare a qualcosa nel STL. L'omissione di un modello di identità e di un funzionario di identità mi ha sempre sconcertato. – Potatoswatter

+0

Hai ragione riguardo al problema di correttezza. "Un'implementazione conforme potrebbe avere estensioni ... purché non alterino il comportamento di nessun programma ben formato" (1.4/8, intro.compliance); Avevo dimenticato esattamente quali erano le regole riguardanti la grammatica, le estensioni e la conformità linguistica. –

1

In §7.1.5.2, continuare a leggere fino alla tabella 7, che contiene l'elenco completo di cosa è consentito come semplice identificatore (che include "unsigned int").

+3

Direi che la tabella non intende definire la nozione di "specificatore di tipo semplice". Inoltre, la formulazione dopo la tabella menziona "più specificatori di tipi semplici". Questa è la dicitura che ci permette di usare 'unsigned int' e' int unsigned' in modo intercambiabile, il che probabilmente significa che 'unsigned int' è in effetti * multiple * semplici specificatori di tipi. – AnT

+0

@AndreyT: questa è stata anche la mia interpretazione. Penso anche che l'intestazione della colonna della tabella "Specifier (s)" implichi altrettanto. –

+0

Hmm ... nella mia copia dello standard, il titolo della tabella è "Specifiers di tipo semplice e i tipi che specificano". Con quel titolo, sembra un pessimo tentativo di credere che qualcosa nella tabella sia * non * un semplice specificatore di tipo. –

-2

7.1.5.2:

il semplice-tipo-specificatori specificare un tipo definito dall'utente precedentemente dichiarata o uno dei types` fondamentale

Ciò implica che unsigned int i = unsigned int() è legale, poiché unsigned int è un tipo fondamentale (e quindi uno specificatore di tipo semplice , vedere 3.9.1).

stesso vale per i tipi come:

long double 
long long 
long long int 
unsigned long 
unsigned long long int 
short int 
... 
+0

Penso che ci sia un errore logico qui: il tuo argomento è che, "Se T è un identificatore di tipo semplice, allora T è un tipo definito dall'utente definito in precedenza o T è uno dei tipi fondamentali. T è un tipo fondamentale, quindi T è un semplice specificatore di tipo "(stai affermando il conseguente). –

+0

@James: Non capisco cosa stai dicendo, la tua domanda affermava che 'T t = T()' è legale per gli specificatori di tipo semplice, e la mia citazione dice che i tipi fondamentali SONO specificatori di tipo semplice, quindi 'unsigned int i = unsigned int() 'è legale. – smerlin

+1

Mi scuso; Evidentemente non avevo ancora abbastanza caffè quando l'ho postato stamattina. Non sono d'accordo con la tua interpretazione che se 'T' è un tipo fondamentale,' T' deve anche un semplice identificatore di tipo. Credo che 'T' possa in effetti essere più semplice specificatore di tipo (ad esempio' unsigned int' è un tipo fondamentale ma è designato da due semplici specificatori di tipo, 'unsigned' e' int'). Penso che ci siano molte dichiarazioni a supporto di ciò, ad es. 3.9.1, nota 40: "Vedere 7.1.5.2 in merito alla corrispondenza tra i tipi e le _sequences_ degli specificatori di caratteri che li designano" (enfasi mia) –