IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Template Heritage et classes imbrique, probleme de compilation


Sujet :

Langage C++

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 13
    Points : 3
    Points
    3
    Par défaut Template Heritage et classes imbrique, probleme de compilation
    Bonsoir,

    je suis face a un probleme etrange ^^'

    En effet j'ai mon code d'un arbre binaire implemente dans un vecteur qui compile correctement.

    Maintenant il est temp d'ajouter des template ^^"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template<typename TYPE>
    Arbre2V<TYPE>::NoeudV* Arbre2V<TYPE>::NoeudV::filsGauche(){
     //mon code
    }
    Bien G++ n'aime pas * il demande un constructeur, destructeur ou operatuer de conversion avant...

    Donc je me demandait comment faire pour passair d'un type de retour Arbre2V::NoeudV* a un type avec template.

    N.B. Arbre2V est en effet une classe template, NoeudV est declare a l'interieur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    template<typename TYPE>
    class Arbre2V : public Arbre2<TYPE>{
    	public:
    		class NoeudV : public Arbre2<TYPE>::Noeud{ /*j'ai du ajouter Arbre2<TYPE>:: sinon il acceptait plus Noeud*/
    			public:
                                friend class Arbre2V<TYPE>;
                                /*Suite de la classe*/
                    };
                    /*Suite de la classe*/
    };
    Ils héritent d'une structure abstraite similaire (Arbre2 en template et Noeud imbrique).

    En ajoutant les template, il met une aussi erreur a la méthode prive d'Arbre2V

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    void copier(int, Noeud*);
    Et G++ dit que Noeud* n'est pas un type, et le transforme en int pour poursuivre ça compilation (ce qui genere naturellement des erreur âpres)

    Avant l'introduction des template, tout cela marchait bien :'(

    Comment faire?

    Merci d'avance

    N.B.2 Je suis oblige d'utiliser a ce type de structure, classe imbrique, par l'énonce.

  2. #2
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 861
    Points
    11 861
    Par défaut
    Chaque fois que tu as une expression template de la forme , le compilateur n'est pas en mesure de déterminer si B est un type ou alors une variable statique, par exemple, car T est justement un type "non fixé" au moment ou tu écris ton code. Il sera fixé que lorsque tu instancieras ta classe. Et il ne sera fixé que pour cette instance. Toujours est-il que le compilo ne peut savoir.
    Donc à chaque fois que A<T>::B désignera un type, tu devras préfixer de typename.
    Ca donne :
    .

    Edit : je viens de voir que tu n'avais apparemment pas cette erreur, ce qui n'est pas normal d'ailleurs.

  3. #3
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Points : 444
    Points
    444
    Par défaut
    Possible de voir le code de ta méthode filsGauche ?

    Sinon pour ta méthode copier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void copier(int, typename Arbre2<TYPE>::Noeud*);

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    C'est quoi cette fonction copier avec un prototype bizarre ?

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 13
    Points : 3
    Points
    3
    Par défaut
    Citation Envoyé par Alp
    Chaque fois que tu as une expression template de la forme , le compilateur n'est pas en mesure de déterminer si B est un type ou alors une variable statique, par exemple, car T est justement un type "non fixé" au moment ou tu écris ton code. Il sera fixé que lorsque tu instancieras ta classe. Et il ne sera fixé que pour cette instance. Toujours est-il que le compilo ne peut savoir.
    Donc à chaque fois que A<T>::B désignera un type, tu devras préfixer de typename.
    Ca donne :
    .

    Edit : je viens de voir que tu n'avais apparemment pas cette erreur, ce qui n'est pas normal d'ailleurs.
    oO j'avais oublie ca. Ca se voit que ce la première fois que je fait du C++ ^^"
    En effet ca compile merci

    bolhrak =>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template<typename TYPE>
    typename Arbre2V<TYPE>::NoeudV* Arbre2V<TYPE>::NoeudV::filsGauche(){
    	typename Arbre2V<TYPE>::NoeudV* ptr = new NoeudV(2*index+2,infos);
    	return ptr;
    }
    En effet la méthode copier passe aussi

    loufoque => En effet la méthode copier utilise les proprietes de l'héritage/polymorphisme pour copier n'importe quel type d'arbre, vers un Arbre2V
    Il me faut alors que en paramètre je puisse lui passer un pointeur vers la classe mere.

    Sans template, il prenait un Noeud*, la il veut un typename Arbre2<TYPE>::Noeud*

    Mais a priori ca reste de meme.

    Sinon une autre question, quand j'hérite NouedV de Noeud, pourquoi je suis oblige de metre Arbre2<TYPE>::Noeud, et pas simplement Noeud comme quand il n'y avait pas de template?

    Merci encore pour m'avoir aider

  6. #6
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Points : 444
    Points
    444
    Par défaut
    Bon suis pas trop expert des classes internes, mais je penses qe tu devrais essayer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template <typename TYPE>
    typename Arbre2V<TYPE>::NoeudV* Arbre2V<TYPE>::NoeudV::filsGauche(){
    	NoeudV* ptr = new NoeudV(2*index+2,infos);
    	return ptr;
    }
    Mon explication (peut-être fausse dans ce cas merci de la corriger) étant que ton type de retour est un type vu de l'extérieur, ta classe NoeudV étant une classe interne il est nécessaire, pour l'extérieur, de la dénommer par son type complet, autrement dit ClasseContenante::ClasseInterne. Par contre une fois dans la définition de la méthode, tu es "dans " la classe interne, bref ce n'est plus une vision externe, donc pas besoin (et illégal) de spécifier le type la contenant.

    Pour le fait de déclarer Arbre2<Type>::Noeud au lieu de Noeud dans ta relation d'héritage, cela vient du mécanisme de compilation des templates.

    Dans le premier cas, sans template :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    class A : public class B {
    //...
    La classe B est examinée avant la fin de la déclaration de la classe A, donc toutes les méthodes, types et autres de la classe B sont disponibles pour A. Dans ton cas, la classe Noeud de Arbre2 est donc disponible dans la classe Arbre2V dès le "début" de la déclaration de ta classe.

    Dans le cas des templates, la classe mère est examinée après la fin de la déclaration de la classe fille (ce qui rend possible le CRTP entre autres), sauf si tu forces explicitement cet examen. Donc ta classe Noeud interne à Arbre2 ne sera disponible quà la fin de la déclaration de ta classe Arbre2V. Hors tu souhaites utiliser cette classe dans la déclaration de Arbre2V. Il faut donc que tu spécifies le type exact pour forcer le compilo à examiner la classe mère.

    C'est un poil plus compliqué que ça vu que l'examen des classes pour les templates se fait en deux temps contre un seul pour les classes classiques, mais je pense (enfin j'espère :p) que ça résume l'idée.

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2006
    Messages : 13
    Points : 3
    Points
    3
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template <typename TYPE>
    typename Arbre2V<TYPE>::NoeudV* Arbre2V<TYPE>::NoeudV::filsGauche(){
    	NoeudV* ptr = new NoeudV(2*index+2,infos);
    	return ptr;
    }
    En effet ca compile bien aussi ^^"

    Par contre je n'ai pas trop compris le reste je doit meme dire que je me suis un peut perdu

Discussions similaires

  1. Templates de classes imbriquées et héritage
    Par progcyb dans le forum Langage
    Réponses: 0
    Dernier message: 18/11/2014, 21h54
  2. Réponses: 4
    Dernier message: 22/11/2010, 14h15
  3. iterator, classe imbriquée, et template
    Par _ash_ dans le forum Débuter
    Réponses: 2
    Dernier message: 01/02/2010, 10h13
  4. probleme compilation classe avec Borland c++ compiler 5.5
    Par softblue dans le forum Autres éditeurs
    Réponses: 2
    Dernier message: 17/06/2004, 15h16
  5. Problemes de compilation avec g++ sous linux
    Par Selimmel dans le forum Autres éditeurs
    Réponses: 3
    Dernier message: 19/09/2003, 13h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo