2010-06-16 18 views

Antwort

16

Wenn eineine abhängig Namen eine verschachtelte Vorlage verweisen verwendet werden, hat der verschachtelte Name mit dem Stichwort template vorangestellt werden, um die Compiler zu helfen, zu verstehen, dass Sie auf eine verschachtelte Vorlage beziehen und den Code richtig

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

Innen main der Name a ist nicht abhängig, weshalb Sie nicht die zusätzliche template Schlüsselwort benötigen. Inside F Name a ist abhängig, weshalb das Schlüsselwort benötigt wird.

Dies ähnelt dem zusätzlichen Schlüsselwort typename, wenn auf verschachtelte Typnamen über einen abhängigen Namen verwiesen wird. Nur die Syntax ist etwas anders.

1

Im ersteren, denkt der Compiler, dass Sie meine ...

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

Andrey Antwort, dass behebt.

0

Beachten Sie, dass es sind Code-Schnipsel, die für sowohl das Schlüsselwort hinzugefügt und nicht hinzugefügt gültig sind, unterschiedliche Ergebnisse jeweils Nachgeben, auch für Vorlagen, die anstelle von ganzen Zahlen Typ Parameter übernehmen.

#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; 
} 

Diese Ausgänge 0 wenn ausführen, ohne das template Schlüsselwort hinzugefügt. Wenn Sie das Schlüsselwort vor f < int() > hinzufügen, gibt es 1 aus.


Erklärung

Die Version ohne das Schlüsselwort parst als

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; 

Und die Version mit dem Stichwort parst als

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

Beachten Sie, dass temp2 ein Null-Zeiger ist (produziert von return T()). Ganz verschiedene Pars, und beide sind gültig! Dies erfordert wirklich eine Möglichkeit, zu disambiguieren - das Schlüsselwort template entsprechend einzufügen.