2010-06-06 14 views
5

Ich versuche zu verstehen, whay ich auf diesem Code eine Fehlermeldung erhalten: (der Fehler unter g ++ Unix-Compiler VS OK kompiliert.)Problem mit Vorlage Vererbung

template<class T> class A { 
public: 
    T t; 
public: 
    A(const T& t1) : t(t1) {} 
    virtual void Print() const { cout<<*this<<endl;} 
    friend ostream& operator<<(ostream& out, const A<T>& a) { 
      out<<"I'm "<<typeid(a).name()<<endl; 
      out<<"I hold "<<typeid(a.t).name()<<endl; 
      out<<"The inner value is: "<<a.t<<endl; 
      return out; 
    } 
}; 

template<class T> class B : public A<T> { 
public: 
    B(const T& t1) : A<T>(t1) {} 
    const T& get() const { return t; } 
}; 

int main() { 
    A<int> a(9); 
    a.Print(); 
    B<A<int> > b(a); 
    b.Print(); 
    (b.get()).Print(); 
    return 0; 
} 

Dieser Code die folgende schenkt Fehler:

main.cpp: in Memberfunktion 'const T & B :: get() const':
main.cpp: 23: Fehler: 't' wurde in diesem Rahmen nicht erklärt

Es habe kompiliert, als ich den Code von B auf diese geändert:

template<class T> class B : public A<T> { 
public: 
    B(const T& t1) : A<T>(t1) {} 
    const T& get() const { return A<T>::t; } 
}; 

Ich kann nicht nur verstehen, was das Problem mit dem ersten Code ist ...
Es macht keinen Sinn, dass ich wirklich brauchen, um zu schreiben „A ::“ every Zeit ...

Antwort

7

Sie können auch this->t verwenden, um auf das Basisklassenschablonenelement zuzugreifen.

In B::get() ist der Name t nicht von dem Vorlagenparameter T abhängig, daher ist es kein abhängiger Name. Die Basisklasse A<T> ist offensichtlich abhängig vom Template-Parameter T und ist somit eine abhängige Basisklasse. Nicht abhängige Namen werden nicht in abhängigen Basisklassen nachgeschlagen. A detailed description of why this is the case can be found in the C++ FAQ Lite.

+2

Die FAQ ist falsch, warum "this ->" funktioniert. Vergleichen Sie es mit dem Standard (betonen Sie von mir). FAQ: "Da dies in einer Vorlage immer implizit abhängig ist, ist dies-> f * abhängig und die Suche ist daher verzögert *, bis die Vorlage tatsächlich instanziiert ist. * An diesem Punkt gelten alle Basisklassen *", Standard: ". .. wird der Basisklassenbereich * nicht während der Suche nach unqualifiziertem Namen überprüft, und zwar entweder zum Zeitpunkt der Definition der Klassenvorlage oder des Members * oder während einer Instanziierung * der Klassenvorlage oder des Members. ". Die FAQ sagt, dass es gefunden wurde, weil es abhängig ist, aber das ist falsch. –

+1

GCC implementiert auch diese falsche Interpretation und als Ergebnis [hat Fehlerberichte geöffnet] (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43282) –