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 :

surcharge fonction template


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Profil pro
    Inscrit en
    Août 2007
    Messages
    190
    Détails du profil
    Informations personnelles :
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Août 2007
    Messages : 190
    Par défaut surcharge fonction template
    Bonjour,

    Voilà je n'arrive pas à comprendre 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
    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
    42
    43
    44
    45
    #include <iostream>
    #include <vector>
    
    template<typename T> (1)
    void adapter(T const& t) {
      t.print();
    }
    
    class A {
    public:
      void print() const {
        std::cout << "A" << std::endl;
      }
    };
    
    template<typename T>
    class B {
    public:
      B(T const& t)
        : t_(t) {
      }
      void print() const {
        adapter(t_);
      }
    
    private:
      T const& t_;
    };
    
    template<typename T> (2)
    void adapter(std::vector<T> const& v) {
      std::cout << v.size() << std::endl;
    }
    
    int main() {
      std::vector<int> v(20);
      A a;
      B<std::vector<int> > b1(v);
      B<A> b2(a);
    
      b1.print();
      b2.print();
    
      return 0;
    }
    Lors que le compilateur instancie la méthode print avec T=std::vector<int> il utilise la fonction template adapter (1) alors que selon moi il devrait choisir la (2) qui est plus "spécialisée". Le plus étrange c'est que si je place la définition de (2) avant la définition de la classe B il n'y a plus d'erreur. J'ai beau chercher je n'arrive pas à trouver d'explications. Donc si quelqu'un pouvait éclairer ma lanterne je lui en serais reconnaissant.

  2. #2
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Parce qu'elle n'est pas declaree au point d'utilisation. Place la avant la classe B.

  3. #3
    Membre expérimenté
    Profil pro
    Inscrit en
    Août 2007
    Messages
    190
    Détails du profil
    Informations personnelles :
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Août 2007
    Messages : 190
    Par défaut
    En fait je viens de trouver dans le standard ce qui justifie l'erreur de compilation.
    Citation Envoyé par Le standard
    In resolving dependent names, names from the following sources are considered:
    — Declarations that are visible at the point of definition of the template.
    — Declarations from namespaces associated with the types of the function arguments both from the instantiation
    context (14.6.4.1) and from the definition context.
    En effet si on place la définition de (2) dans le namespace std (je sais c'est pas bien mais c'est juste pour tester) alors plus de problème.
    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
    42
    43
    44
    45
    46
    47
    #include <iostream>
    #include <vector>
    
    template<typename T>
    void adapter(T const& t) {
      t.print();
    }
    
    class A {
    public:
      void print() const {
        std::cout << "A" << std::endl;
      }
    };
    
    template<typename T>
    class B {
    public:
      B(T const& t)
        : t_(t) {
      }
      void print() const {
        adapter(t_);
      }
    
    private:
      T const& t_;
    };
    
    namespace std {
    template<typename T>
    void adapter(std::vector<T> const& v) {
      std::cout << v.size() << std::endl;
    }
    }
    
    int main() {
      std::vector<int> v(20);
      A a;
      B<std::vector<int> > b1(v);
      B<A> b2(a);
    
      b1.print();
      b2.print();
    
      return 0;
    }
    Désolé. J'aurais dû faire plus attention.

  4. #4
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Rassures-toi, la recherche des noms en deux temps pour les templates n'est pas la chose la mieux connue du C++ D'autant que ca ne m'etonnerait pas que certains compilateurs ne l'implementent toujours pas.

  5. #5
    Membre expérimenté
    Profil pro
    Inscrit en
    Août 2007
    Messages
    190
    Détails du profil
    Informations personnelles :
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Août 2007
    Messages : 190
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    D'autant que ca ne m'etonnerait pas que certains compilateurs ne l'implementent toujours pas.
    En effet le code que j'ai donné dans mon premier message ne pose aucun problème au compilateur de Visual C++.
    Ce n'est pas la première fois que je constate que Visual ne respecte pas du tout la norme quand il s'agit des templates.

  6. #6
    Alp
    Alp est déconnecté
    Expert confirmé

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

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Et ça ne sera pas la dernière.

    Par contre, pourquoi voulais-tu trouver une solution sans déplacer la "spécialisation" avant B ?
    Tu peux expliquer la situation qui t'y pousse ?

  7. #7
    Membre expérimenté
    Profil pro
    Inscrit en
    Août 2007
    Messages
    190
    Détails du profil
    Informations personnelles :
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations forums :
    Inscription : Août 2007
    Messages : 190
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    Parce qu'elle n'est pas declaree au point d'utilisation. Place la avant la classe B.
    Oui comme je l'ai précisé dans mon premier message le fait de placer la définition de (2) avant B règle le problème. Mais le code que j'ai donné n'est qu'un exemple. Normalement la définition de B et de la fonction template adapter seraient placées dans un header auquel on ne doit pas toucher.

Discussions similaires

  1. Surchargé une fonction template avec template
    Par SKone dans le forum Langage
    Réponses: 2
    Dernier message: 12/10/2014, 20h00
  2. Surcharge de fonction template
    Par camboui dans le forum C++
    Réponses: 3
    Dernier message: 09/05/2011, 11h25
  3. Surcharge particulière de fonctions templates ?
    Par rulianf dans le forum C++
    Réponses: 6
    Dernier message: 04/02/2009, 14h07
  4. fonctions template
    Par romeo9423 dans le forum Langage
    Réponses: 12
    Dernier message: 22/01/2005, 16h13
  5. Fonctions template+friend sous VC7
    Par patapetz dans le forum MFC
    Réponses: 12
    Dernier message: 24/09/2004, 11h16

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