2011-05-23 20 views
10

Dire che ho un oggetto di alcune classi di classi stl obj. Posso definire un altro oggetto dello stesso tipo in questo modo:Comportamento di decltype

decltype(obj) obj2; 

Ma non posso dichiarare iteratore per il contenitore in questo modo:

decltype(obj)::iterator it = obj.begin(); 

Perché? Sto facendo qualcosa di sbagliato?

risposta

15

Il codice è ben formato secondo l'ultima bozza di C++ 0x (FDIS) . Questo era un cambiamento tardivo che non è stato ancora implementato dal compilatore di Visual Studio.

Nel frattempo, una soluzione è quella di utilizzare un typedef:

typedef decltype(obj) obj_type; 
obj_type::iterator it = obj.begin(); 

EDIT: Il capitolo e il versetto rilevante è 5.1.1/8:

 
qualified-id: 
    [...] 
    nested-name-specifier templateoptunqualified-id 

nested-name-specifier: 
    [...] 
    decltype-specifier :: 

decltype-specifier: 
    decltype (expression) 

e per amor di completezza :

The original core issue

Proposal for wording

+0

Grazie @JohannesD.Se modifichi la tua risposta aggiungendo il numero di paragrafo della bozza finale che dice questo accetterò la tua risposta. –

+0

@Mihran - Ecco qui :) – JohannesD

7

È a causa del modo in cui viene analizzata la lingua.

decltype(obj)::iterator it = obj.begin(); 

si vuole che diventi

(decltype(obj)::iterator) it; 

Ma in realtà, diventa

decltype(obj) (::iterator) it; 

devo ammettere, sono stato anche sorpreso di vedere che questo era il caso, come sono certo di averlo fatto prima. Tuttavia, in questo caso, si potrebbe utilizzare auto, o anche decltype(obj.begin()), ma in aggiunta, è possibile fare

typedef decltype(obj) objtype; 
objtype::iterator it; 
+0

Grazie per 'auto'. Ma il typedefing non è una buona idea secondo me. Lo sto facendo per evitare il typedefing. –

+0

@Mihran Hovsepyan: perché? Il tuo codice dipende da uno standard 'typedef'- difficilmente' typedef'-free. 'typedef' è difficilmente evitabile in C++ così com'è. – Puppy

+0

la mia definizione di classe è nell'intestazione, ma i metodi in cpp, quindi ogni volta durante l'implementazione di cpp dovrei aprire l'intestazione e cercare qual è il tipo di membro. Ma come ogni programmatore sto cercando di essere pigro)) –

2

Ancora un'altra soluzione fino parser VC++ s 'è fissato in modo da riflettere la FDIS è quello di utilizzare il std::identity<> metafunction:

std::identity<decltype(obj)>::type::iterator it = obj.begin(); 
+1

FWIW, 'std :: identity' è stato rimosso, quindi è effettivamente dipendente da VC2010. (È abbastanza semplice scriverlo, però.) – GManNickG

+0

@GMan: Giusto, l'ho solo menzionato perché la domanda dell'OP era specifica per VC++ 2010. : -] – ildjarn