Newsgroup: it.comp.lang.c++
Titolo: typename

Non mi e' ancora del tutto chiaro l'uso di questa keyword nel contesto
della esplicitazione di un tipo .
Il seguente codice compila benissimo senza alcun uso della keyword
typename.
class QAZ {
   public :
   typedef QAZ* pQAZ  ;
   int A ;
    };
  template <class T>
  class WSX {
     public :
     typedef T::pQAZ ptr ;
     ptr b ;
     } ;
 WSX<QAZ> wsx ;

      typedef T::pQAZ ptr ;
Qua il compilatore deve segnalare un errore.
T::qualcosa non puo` essere usato come un tipo, a meno che non sia
preceduto da typename.  Il fatto che WSX sia instanziato solo con tipi
che definiscono pQAZ come tipo (e non come dato) e` ininfluente,
l'errore rimane.
La definizione corretta e`:   typedef typename T::pQAZ ptr;
        Mauro

 qualcuno mi sa spiegare cos'è un typename?
la questione non e` semplicissima...
partiamo dall'inizio: quando il compilatore deve compilare un sorgente 
prima di tutto ne fa il parsing: il parser prende il sorgente e lo 
elabora in modo da avere una struttura facile da analizzare 
successivamente; purtroppo la sintassi del C (e di conseguenza del C++) 
e` semi-ambigua e ci sono dei casi in cui il parser e` un po' in 
difficolta`; considera ad esempio questo:
int x = 0;
// typedef int foo // per ora ignora questo typedef
void foo(int);
void bar()
{
        foo(x);
}
A prima vista sembra tutto semplice: bar() richiama foo() utilizzando 
come parametro la variabile globale x. Ora prova a decommentare il 
typedef e a commentare la "void foo(int)"; quando il compilatore 
incontra la riga "foo(x)" la "vede" come se fosse:
        int (x);
in questo caso le parentesi sono considerate superflue e quindi la riga 
incriminata ha l'effetto di *definire una variabile locale x di tipo 
int*. Come puoi vedere la *stessa* riga e` interpretata in modo 
completamente diverso a seconda se foo e` un tipo o una funzione.
Sino a che scriviamo codice "normale" non si pone il problema, dato che 
il compilatore sa sempre se un nome e` riferito ad un tipo o una 
funzione e quinidi sa anche come interpretare le ambiguita`. Ma 
considera il template:
template<class T>
void bar()
{
        T::foo (x);
}
come fa il compilatore a sapere se T::foo e` un tipo o (ad esempio) una 
funzione statica? Non lo puo` sapere fino a che non si istanzia il 
template, ma il parser deve saperlo *prima*, al momento di analizzare il 
sorgente; il comitato di standardizzazione ha deciso che se ci si deve 
riferire ad un tipo definito in una classe parametro di template si deve 
usare la keyword "typename"; quindi se ci aspettiamo che T::foo sia un 
tipo dobbiamo scrivere:
template<class T>
void bar()
{
        typename T::foo (x); // le parentesi sono superflue
}
Il tuo caso e` esattamente analogo a questo: il compilatore non puo` 
sapere cosa sia vector<T>::iterator sino a che non istanzia il template, 
quindi devi usare typename per risolvere l'ambiguita`. Poi succede che 
il g++ e` particolarmente intelligente e riesce a capire lo stesso cosa 
vuoi fare, pero` ti informa che a norma di standard dovresti mettere 
typename.
ciao Anto
-- 
"Computer science is not about computers any more than astronomy
is about telescopes." -- EW Dijkstra

e` una estensione del compilatore. 
Ringrazio entrambi per la chiarezza.
Quindi diciamo che dovrei aver capito la differenza solo che il mio
compilatore la tiene per se e non me lo dice .
saluti