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 & espaces de nom


Sujet :

Langage C++

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut Template & espaces de nom
    Hello,

    Soit X un espace de nommage, A, B, C... des classes appartenant à cet espace de nommage, et Y un type défini dans chacune de ces classes.

    Je voudrais faire ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    template<typename T>
    struct maClasse
    {
        X::T::Y mPouet;
    };
    Apparemment, le compilateur n'en veut pas.

    Pas possible ?

  2. #2
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014

  3. #3
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Chez moi, le code suivant compile bien (g++).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    namespace X
    {
        struct A{ struct Y{}; };
        struct B{ struct Y{}; };
        struct C{ struct Y{}; };
    }
     
    template <typename T> class U
    {
        X::A::Y y;
    };
     
    int main(int argc, char const *argv[])
    {
        U<int> u;
    }
    Tu peux mettre un exemple minimal qui reproduit l'erreur ?

    Edit, grillé
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  4. #4
    screetch
    Invité(e)
    Par défaut
    typename X::T::Y ?

    aussi, quand tu as une erreur de compilation ou d'execution, copier-coller l'erreur ca mange pas de pain

  5. #5
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Bonjour,

    Je ne sais pas comment le comité à rendu plus permissives (*) les règles pour typename en C++1x, mais avant il aurait fallut utiliser une typename dans ce cas (on est dans un template et l'identifiant Y depend de T et est qualifié (**) ).

    (*) Cependant dans la norme on trouve ce code qui me fait dire qu'il est au moins autorisé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    template<class T> struct X : B<T> {
    typename T::A* pa;
    void f(B<T>* pb) {
    static int i = B<T>::i;
    pb->j++;
    }
    };
    (**) Et on n'est pas dans la déclaration des classes de bases ni dans une liste d'initialisation.

    PS: GCC a peut-être anticipé sur le comité et autorisé cette expression (c'est un cas non ambigue pour le compilateur).

    Edit: J'avais pas vu le message de screetch, le mien est inutile donc.

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par Arzar Voir le message
    Ce que je chercher à faire, c'est plutôt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include <string>
    namespace X
    {
    	struct A
    	{
    		typedef std::string Y ;
    	};
    }
     
    template<typename T>
    struct maClasse
    {
        X::T::Y mPouet;
    };
     
    int main()
    {
    maClasse<int> m;
     
      return 0;
    }
    J'ai changé le type sur la ligne 4, et accessoirement viré la méthode dans la classe, afin de rester sur l'essentiel.

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template <typename T> class U
    {
        X::A::Y y;
    };
    Tu n'utilises pas le type templatisé.

    Citation Envoyé par Davidbrcz Voir le message
    Tu peux mettre un exemple minimal qui reproduit l'erreur ?
    cf lien donné juste au-dessus.

  8. #8
    screetch
    Invité(e)
    Par défaut
    ah ben oui forcément

    pourquoi tu veux specifier X::T, le type que tu recois c'est bien T non?

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par screetch Voir le message
    ah ben oui forcément

    pourquoi tu veux specifier X::T, le type que tu recois c'est bien T non?
    Oui, mais comme le type passé n'est pas connu de l'espace global, la déclaration de la classe ne le trouve pas.
    La solution plus intellligente est en fait de qualifier lors de l'appel (quoique sur mon cas concret, je n'y arrive pas encore), mais je me demandais pourquoi, d'un point de vue langage, ça ne fonctionnait pas.

  10. #10
    screetch
    Invité(e)
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include <string>
    namespace X
    {
            struct A
            {
                    typedef std::string Y ;
            };
    }
     
    template<typename T>
    struct maClasse
    {
        typename T::Y mPouet;
    };
     
    int main()
    {
    maClasse<X::A> m;
     
      return 0;
    }
    je ne vois pas le problème...
    Dernière modification par 3DArchi ; 11/10/2011 à 07h49.

  11. #11
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Oui, quand tu qualifies lors de l'appel, il n'y a aps de problème.

  12. #12
    screetch
    Invité(e)
    Par défaut
    tu veux juste savoir pourquoi ca ne marche pas?
    j'avoue que moi ce qui m'intrigue c'est plutôt pourquoi ca devrait fonctionner

    tu as une classe template qui dépend d'un type en entrée
    tu lui donne ce type, mettons X::A
    ensuite, la classe template ne doit pas avoir besoin de savoir dans quel espace de nom son entrée vient. La tu utilises le type T comme si c'etait un "nom" de classe, alors qu'en fait du point de vue du compilateur c'est la classe, pas son nom.

    Enfin je ne vois pas bien la logique derrière.

  13. #13
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par screetch Voir le message
    tu as une classe template qui dépend d'un type en entrée
    tu lui donne ce type, mettons X::A
    ensuite, la classe template ne doit pas avoir besoin de savoir dans quel espace de nom son entrée vient.
    Pourquoi ?
    Quand une crée une classe non template, on est bien parfois amené à rpéciser où il peut la trouver.
    Pourquoi pas dans une classe template ?

    Citation Envoyé par screetch Voir le message
    La tu utilises le type T comme si c'etait un "nom" de classe, alors qu'en fait du point de vue du compilateur c'est la classe, pas son nom.
    Les templates sont ils me semblent supposés permettre de donner un paramètre template partout où l'on pourrait mettre un nom de classe.

    D'ailleurs, tu me reproches de raisonner sur les noms, mais dans les paramètres templates, on met bien typename, il me semble, non ?

  14. #14
    screetch
    Invité(e)
    Par défaut
    ben c'est toi qui prend le compilateur a l'envers pas moi
    je voulais pas etre mechant mais je voulais juste dire que je ne voyais pas ta logique.

    Le template recoit un type en paramètre, car en fait l'appelant (celui qui instancie le template) lui a donné cette information là; c'est donc a l'appelant d'avoir le nom complet.
    à l'interieur de la classe template, tu n'es pas censé savoir ou se trouve le type, c'est bien a l'appelant de faire ca pour le template.

  15. #15
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par screetch Voir le message
    à l'interieur de la classe template, tu n'es pas censé savoir ou se trouve le type, c'est bien a l'appelant de faire ca pour le template.
    C'est ce que j'avais fini par comprendre.

    Mais je m'interroge sur la raison de cette restriction.

  16. #16
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    Les espaces de noms sont un moyen d'enrichir un nom complet d'elements déclarés. Ce n'est pas un moyen de définir un térritoire (contrairement aux autres languages en fait).

    Autrement dit : si tu dois manipuler un type, il embarque son nom canonique (complet) et tu ne peux pas le composer à la volée dans du code générique.

    Avec les templates, tu manipules des types, pas du texte. Là ce que tu veux faire c'est de l'ordre de la macro, c'est hors language, c'est de la composition de nom et donc de texte.

  17. #17
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    OK, c'est plus clair. Merci.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [d6][expert WSDL] problème d'espace de nom.
    Par tchup dans le forum Web & réseau
    Réponses: 1
    Dernier message: 01/09/2005, 14h46
  2. Supprimer les espaces des noms de fichier
    Par Cathy dans le forum Linux
    Réponses: 20
    Dernier message: 04/08/2005, 17h13
  3. [typedef] protection à travers les espaces de noms
    Par PINGOUIN_GEANT dans le forum C++
    Réponses: 7
    Dernier message: 02/02/2005, 20h21
  4. Réponses: 6
    Dernier message: 06/10/2004, 12h59

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