2010-06-06 2 views
5

J'essaie de comprendre whay je reçois une erreur sur ce code: (l'erreur est sous compilateur g ++ unix VS compile OK.)avec l'héritage du modèle

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

Ce code donne les éléments suivants erreur:

main.cpp: en fonction membre 'const T & B :: get() const':
main.cpp: 23: erreur: 't' n'a pas été déclaré dans ce champ

Il a compilé quand je modifié le code de B à ceci:

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

Je ne comprends pas tout ce qui est le problème avec le premier code ...
Il n'a pas de sens que je vraiment besoin d'écrire « A :: » tous les time ...

Répondre

7

Vous pouvez également utiliser this->t pour accéder au membre du modèle de classe de base.

Dans B::get(), le nom t ne dépend pas du paramètre de modèle T, il ne s'agit donc pas d'un nom dépendant. La classe de base A<T> dépend évidemment du paramètre modèle T et est donc une classe de base dépendante. Les noms non dépendants ne sont pas recherchés dans les classes de base dépendantes. A detailed description of why this is the case can be found in the C++ FAQ Lite.

+2

La FAQ est fausse sur la raison pour laquelle "this->" fonctionne. Comparez-le avec la norme (souligner par moi). FAQ: "Comme ceci est toujours implicitement dépendant dans un template, ceci-> f * est dépendant et la recherche est donc différée * jusqu'à ce que le template soit réellement instancié, * à quel point toutes les classes de base sont considérées *", Standard: ". .. la portée de la classe de base * n'est pas examinée * lors de la recherche de noms non qualifiés au moment de la définition du modèle de classe ou du membre * ou lors d'une instanciation * du modèle de classe ou du membre. ". La FAQ dit que c'est trouvé parce que c'est dépendant, mais c'est faux. –

+1

GCC implémente également cette mauvaise interprétation, et par conséquent [a des rapports de bogues ouverts] (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43282) –