Come spiegato qui, il punto è che la "compilazione" di un template avviene in due fasi: c'è una prima verifica sintattica "di base", quindi, nel momento in cui viene effettivamente istanziato (specificando un tipo), avviene la compilazione vera e propria.Originariamente inviato da MegaAlchimista
Francamente l'unica spiegazione che ho trovato mi risulta aimè molto ostica e non riesco realmente a comprenderla
Ora, nella prima fase vengono verificati diversi aspetti sintattici fondamentali, senza però sapere ancora esattamente che tipo verrà passato come parametro template.
In questo passaggio, tuttavia, qualunque espressione del tipo tipo<T>::qualcosa è sostanzialmente ambigua, dato che, anche se nella definizione di base di tipo<T> qualcosa è un typedef o in generale rappresenta un tipo, nulla impedisce che una specializzazione particolare della classe definisca qualcosa come, ad esempio, campo statico (al quale ci si riferisce con la medesima sintassi, ma ha ovviamente una semantica completamente diversa).
Per questo motivo, lo standard impone che, durante questo primo passaggio, tutti gli identificatori del tipo tipo<T>::qualcosa vengano considerati a priori come un valore, e non come un tipo. Da questo il messaggio di errore: iterator è il "nome dipendente" (dall'effettiva definizione di std::list<T>) e non viene considerato come un tipo, ma come un valore.
Per specificare al compilatore che invece il nome dipendente a cui ti riferisci è un tipo (e dunque è ammissibile usarlo come tipo restituito per la tua funzione) si usa la keyword typename, che forza l'interpretazione del nome dipendente come tipo.
Il problema è che non è possibile avere dei typedef con parametri template (o meglio, puoi avere un typedef all'interno di una classe template, ma non puoi avere un typedef "a sé stante" parametrizzato con un parametro template); tuttavia, in C++11 (l'ultima revisione dello standard) è possibile fare qualcosa del genere con la keyword using.Inoltre ho un altro problema:
Nel file che sto scrivendo list::iterator appare in numerosi punti, avevo quindi pensato di usare una comoda typedef, come potrebbe essere questa
ovviamente non compila e da lo stesso problema di cui sopra.. in questo caso non posso però premettere la keyword typename : esistono altri metodi per ottenere lo stesso risultato?codice:template<class T> typedef std::list<T>::iterator listIterator<T>;
http://en.wikipedia.org/wiki/C%2B%2B11#Alias_templates