2010-12-16 2 views
2
template <class A,class B> 
class H { 

public: 
    A a; 
    B b; 
    void fac(); 
}; 

template <class B,class A> 
void H<B,A>::fac() { 
} 

Was bedeutet was genau H? Seit ich erklärte template <class B,class A>, <B,A> schien bedeutungslos ....Ein Puzzle beim Lernen Templates in C++

Kann mir jemand helfen ?? Thnx !!

+0

Damit dies funktioniert, müsste void fac() statisch sein. – fingerprint211b

+0

Ich meine, warum kann ich nicht schreiben, H :: fac() {} anstelle von H . ?? – Determinant

Antwort

4

Es gibt keine Sprachregel Sie verhindert, etwas zu tun

template<class B> void H<B, B>::fac() { 
} 

und in der Tat kann es für jegliche ausdrückliche oder teilweise Spezialisierungen erforderlich sein. Da der große, große Teil des Template-Codes direkt inline ist, ist dies jedoch von geringer Bedeutung.

Zum Beispiel:

template<class A, class B> 
class H 
{ 
public: 
    A a; 
    B b; 

    void fac(); 
}; 
template<class A> class H<A, A> { 
public: 
    A a, b; 
    void fac(); 
}; 

template<class A, class B> void H<A, B>::fac() { 
} 

template<class B> void H<B, B>::fac() { 
} 
+0

Dies sollte eine korrekte Antwort sein. – Nawaz

+0

Es scheint nicht die richtige Antwort zu sein, da kein Compiler diesen Code zu akzeptieren scheint. – UncleBens

+0

@UncleBens: Überprüfen Sie meine Bearbeitung. Meine ursprüngliche Aussage war nicht so klar, wie es sein sollte, aber ich bin völlig richtig und mein Compiler akzeptiert diesen Code gerne. – Puppy

0

Normalerweise setzen Sie die Vorlage Implementierung in der Template-Deklaration selbst:

template<class A, class B> 
class H 
{ 
public: 
    A a; 
    B b; 

    void fac() 
    { 
     // Implementation 
    } 
}; 

jedoch it is also possible to separate it out:

template<class A, class B> 
class H 
{ 
public: 
    A a; 
    B b; 

    void fac(); 
}; 

template<class A, class B> 
void H<A, B>::fac() 
{ 
    // Implementation 
} 

Diese beiden Schnipsel das Gleiche bedeuten. So funktioniert die C++ Syntax. Beachten Sie, dass sich der Bezeichner H im ersten Code-Snippet nicht auf eine tatsächliche Klasse bezieht. Es bezieht sich auf eine Vorlagenklasse, die sich von einer normalen Klasse unterscheidet. H ist der Bezeichner einer -Familie von Klassen, die ähnlich sind, aber unterschiedliche Vorlagenparameter verwenden. Deshalb müssen Sie H<A, B> und nicht nur H sagen.

Denken Sie darüber nach, wie es funktioniert in der Regel für Nicht-Template-Klassen:

class NonTemplateH 
{ 
public: 
    int a; 
    short b; 

    void fac(); 
}; 

void NonTemplateH::fac() 
{ 
    // Implementation 
} 

Sie können sehen, wie sie ähnlich sind.

+0

das beantwortet seine Frage nicht wirklich. – Nawaz

+0

@Nawaz: Huh? Das OP fragte: "Warum kann ich nicht void H :: fac() {} anstelle von H schreiben?" Ich habe das ausdrücklich angesprochen, indem ich sagte, 'H' bezieht sich nicht auf eine Klasse, sondern auf eine Klasse von Klassen kann neue Klassen "erzeugen". Wie beantwortet das nicht seine Frage? –

+0

@In silico: Nein, das hat er nicht gefragt. er fragte, was bedeutet "H "? Er deutet an, dass er schreiben soll "H ", nicht "H "? – Nawaz

0

Sie gefragt:

Da ich erklärte Vorlage <class B,class A>, <B,A> schien bedeutungslos zu sein ....

Nein, das nicht bedeutungslos ist. Um zu verstehen, dass, sollten Sie diesen Code:

template <class A,class B> 
class H { 

    template<class C> //note this line! 
    void fac(); 
}; 

Hinweis: Nun fac() ist eine Funktionsvorlage. Sie haben es so zu definieren:

template <class A,class B> //as usual. 
template <class C> //notice this line especially! (not so usual) 
void H<A,B>::fac() 
{ 
    //your code 
} 

H<A,B> benötigt wird, weil es den Compiler, dass A and B sind Template-Parameter an die class template H nicht auf die Funktionsvorlage fac() erzählt. C ist der Tempate-Parameter für die Funktionsvorlage. Beachten Sie, dass ich in der Definition fac<C>() nicht geschrieben habe. Compiler versteht es automatisch.

Sie können auch das Symbol A und B austauschen.Aber wenn Sie das tun, tun Sie dies konsequent.

0

Der Unterschied zwischen

template <class A, class B> 
void H<A, B>::foo() 

und

template <class A, class B> 
void H::foo() 

ist, dass im zweiten Fall foo eine Funktionsschablone H in einer Nicht-Template-Klasse ist.

Sie können H nur ohne die Vorlagenargumente im Klassenbereich H verwenden. Dieser Teil der Definition gehört immer noch zum globalen Geltungsbereich, wo Sie explizit sagen müssen, was H ist.