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 :

STL et classe template


Sujet :

Langage C++

  1. #1
    Membre expérimenté
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Par défaut STL et classe template
    Bonjour,
    Pouvez vous m'expliquer pourquoi le code suivant ne compile pas ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <list>
     
    template<class T>
    struct A {
        T t;
    };
     
    template<class T>
    struct B {
        std::list<A<T> >::iterator i;
    };
    Ce n'est probablement pas une question nouvelle, mais je n'ai aucune idée de quelle recherche faire. Ce serait une seconde question.

    Merci d'avance

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 393
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 393
    Par défaut
    Je n'ai pas testé, mais ceci devrait compiler:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <list>
     
    template<class T>
    struct A {
        T t;
    };
     
    template<class T>
    struct B {
        typename std::list<A<T> >::iterator i;
    };
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typename std::list<A<T> >::iterator i;

    Sinon le compilo ne sait pas que A est un type .

    edit : grilled... et puis bien :p

  4. #4
    Membre expérimenté
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Par défaut
    Hmm, A est pourtant défini juste au dessus.
    Qu'est ce cela pose comme problème au compilateur ?

    Si c'est A qui pose problème, pourquoi ceci marche-t-il ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template<class T>
    struct B {
        std::list<A<int> >::iterator i;
    };

  5. #5
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    C'est la norme :
    A name used in a template declaration or definition and that is dependent on a template-parameter is assumed not to name a type unless the applicable name lookup finds a type name or the nam is qualified by the keyword typename
    Dans ton dernier exemple, tu n'utilises pas ton paramètre template pour instancier ton itérateur de liste.

    P.S.: j'ai toujours des craintes quand je vois un iterateur membre d'une classe. Es-tu sûr de ta conception ?

  6. #6
    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
    Par défaut
    std::list<T>::iterator peut être un type mais std::list<U>::iterator peut être une variable.
    Les instanciations de templates sont totalement indépendantes car spécialisables.

    C'est pour ça qu'il faut mettre typename.

  7. #7
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par loufoque Voir le message
    std::list<T>::iterator peut être un type mais std::list<U>::iterator peut être une variable.
    Les instanciations de templates sont totalement indépendantes car spécialisables.

    C'est pour ça qu'il faut mettre typename.
    D'ailleurs, j'ai trouvé un truc comme ça dans Boost.Scope Exit, que j'ai mis quand même un bout de temps avant de comprendre :
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
    namespace boost { namespace scope_exit { namespace aux {
     
        template<int> struct declare;
     
        typedef void* declared;
        struct undeclared { declared dummy[2]; };
     
        template<>
        struct declare<sizeof(undeclared)>
        {
            template<int>
            struct apply
            {
                declared value;
                friend void operator>(bool, const apply&) {}
            };
        };
     
        template<>
        struct declare<sizeof(declared)>
        {
            static const int apply = 0;
        };
    } } }
     
    extern boost::scope_exit::aux::undeclared boost_scope_exit_args; 
     
    // ... 
    // bloc d'une méthode/fonction :
    {
       //....
       boost::scope_exit::aux::declare<sizeof(boost_scope_exit_args)> ::apply<0> boost_scope_exit_args; 
    // ici boost::scope_exit::aux::declare<sizeof(boost_scope_exit_args)> ::apply désigne un type
    // celui de declare<sizeof(undeclared)>
     
       //...
       boost::scope_exit::aux::declare<sizeof(boost_scope_exit_args)> ::apply<0> boost_scope_exit_args; 
    // ici boost::scope_exit::aux::declare<sizeof(boost_scope_exit_args)> ::apply désigne un membre
    // celle de declare<sizeof(declared)>
    }

  8. #8
    Membre expérimenté
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    C'est la norme :
    [...]la norme[...]
    Dans ton dernier exemple, tu n'utilises pas ton paramètre template pour instancier ton itérateur de liste.

    P.S.: j'ai toujours des craintes quand je vois un iterateur membre d'une classe. Es-tu sûr de ta conception ?
    Merci pour la citation.

    Et pas d'inquiétude, j'utilise bien l'itérateur dans une boucle, c'était juste pour donner un exemple minimal.

    Citation Envoyé par loufoque Voir le message
    [...]std::list<U>::iterator peut être une variable.[...]
    Toujours pas très clair. "iterator" pourrait être le nom d'une variable de std::list<U>, qui cacherait le type défini dans std::list<> ?

  9. #9
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Ulmo Voir le message
    Merci pour la citation.

    Et pas d'inquiétude, j'utilise bien l'itérateur dans une boucle, c'était juste pour donner un exemple minimal.



    Toujours pas très clair. "iterator" pourrait être le nom d'une variable de std::list<U>, qui cacherait le type défini dans std::list<> ?
    Rien ne t'empêche d'écrire quelque chose comme ça :
    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
     
    struct A{};
    #include <list>
    namespace std{
       template<>
    struct list<A>
    {
       static const int const_iterator=0;
    };
    }
     
    int main()
    {
       return std::list<A>::const_iterator;
    }
    Certes c'est très douteux comme code, mais ici std::list<A>::const_iterator désigne une variable ...

  10. #10
    Membre expérimenté
    Inscrit en
    Décembre 2003
    Messages
    272
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 272
    Par défaut
    OK, amusant.

    Merci pour vos réponses.

  11. #11
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Salut,

    Quand on sait que la forme canonique pour créer une boucle est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for( < <type> nom = valeur_de_depart>;<nom comparaison valeur_arrivee>; <pas>)
    on remarque que la manière "classique" de créer une boucle sur une des collections de la STL te montre bel et bien qu'il s'agit d'un type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for(std::collection<type>::iterator it=col.begin(); it!=col.end();++it)
        (*it).doSomething
    (ou collection est le type de structure "dynamique" utilisée)
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Problèmes de fonctions membres de classe templates, gcc3.3.6
    Par yves.dessertine dans le forum Autres éditeurs
    Réponses: 12
    Dernier message: 17/10/2005, 21h36
  2. Trouver le Type d'une classe template dynamiquement ?
    Par Serge Iovleff dans le forum Langage
    Réponses: 3
    Dernier message: 23/09/2005, 16h48
  3. [DLL/classe template] problème de link
    Par Bob.Killer dans le forum C++
    Réponses: 7
    Dernier message: 31/08/2005, 18h56
  4. Class template hérité
    Par Azharis dans le forum Langage
    Réponses: 4
    Dernier message: 24/06/2005, 22h03
  5. 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