2010-06-16 22 views

risposta

16

Quando un dipendente nome viene usato per riferirsi a un modello nidificato, il nome nidificato deve essere anteporre la parola template per aiutare il compilatore capire che ci si riferisce a un modello nidificato e analizzare il codice correttamente

template <typename T> 
void F(A<T> &a) 
{ 
    a.template f<0>(); 
} 

All'interno main il nome a non dipende, motivo per cui non è necessario il template parola chiave in più. Il nome interno F nome a dipende, motivo per cui è necessaria la parola chiave.

Questo è simile alla parola chiave typename aggiuntiva quando si fa riferimento a nomi di tipi annidati tramite un nome dipendente. Solo la sintassi è leggermente diversa.

1

Nel primo caso, il compilatore pensa che vuoi dire ...

a.f < 0 ...gibberish.... 

risposta di Andrey risolve questo.

0

Si noti che ci sono frammento di codice che sono validi per sia la parola aggiunta e non aggiunti, ottenendo risultati diversi in ogni caso, anche per i modelli che accettano i parametri al posto di interi tipo.

#include <iostream> 

struct A { 
    template<typename T> 
    static A f(T) { 
    return A(); 
    } 

    template<typename T> operator T() { return T(); } 
}; 

template<typename U> 
int g() { 
    U u; 
    typedef A (*funcPtrType)(int()); 
    return !(funcPtrType)u.f < int() > (0); 
} 

int main() { 
    std::cout << g<A>() << std::endl; 
} 

Emette 0 quando viene eseguito senza la parola chiave template aggiunto. Se aggiungi la parola chiave prima dello f < int() >, viene emessa 1.


Spiegazione

La versione senza la parola chiave analizza come

funcPtrType temp1 = (funcPtrType)u.f; // taking func address 
bool temp2 = !temp1;     // temp2 == false 
bool temp3 = temp2 < int();   // temp3 == false 
bool temp4 = temp3 > (0);    // temp4 == false 
return temp4; 

E la versione con la parola chiave analizza come

A temp1 = u.template f < int() > (0);  // function call 
funcPtrType temp2 = (funcPtrType) temp1; // temp2 == 0 
bool temp3 = !temp2;      // temp3 == true 
return temp3; 

noti che temp2 è un puntatore nullo (prodotta per return T()). Intere parses differenti, ed entrambi sono validi! Questo ha davvero bisogno di un modo per disambiguare, ovvero inserire la parola chiave template come appropriato.