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

 C++ Discussion :

Specialisation de function template


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 57
    Par défaut Specialisation de function template
    Bonjour a tous.

    Les exemples et tutoriaux que j'ai pu voir ne sont pas suffisament explicites sur la specialisation d'une fonction template (definition et utilisation). Un ancien fil m'a apporte un debut de reponse mais j'aimerais clarifier quelques points grace a vous.

    Si je mets ceci dans un .h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    // Template de base
    template <typename InputIt> 
    void print(InputIt first, InputIt last) {
        std::cout << "Generic" << std::endl;
    }
     
    // Template explicite pour les std::vector<double>
    // Pas de spacialisation partielle possible pour les function template
    template <> 
    void print<std::vector<double>::iterator>(std::vector<double>::iterator first, std::vector<double>::iterator last) {
        std::cout << "Size: " << last - first << std::endl;
    }
    J'obtiens sous VC++ error LNK2005 (already defined) et fatal error LNK1169: one or more multiply defined symbols found

    Trois solutions marchent a priori (meme si dans les exemples que j'ai pu voir par ailleurs, ils utilisent cette forme sans aucun avertissement).

    1- Rajouter inline ..
    2- Separer dans le .cc la definition qui ne doit plus contenir le mot-cle template
    3- Declarer et definir une fonction non template.

    Qu'est-ce qui se passe exactement ? La specialisation totale ne sert donc a rien ??? D'ailleurs, bizarrement, si je mets en meme temps les declarations suivantes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    template <> 
    void print<std::vector<double>::iterator>(std::vector<double>::iterator first, std::vector<double>::iterator last);
    void print(std::vector<double>::iterator first, std::vector<double>::iterator last);
    aucune complainte du compilateur !

    Autre chose. Au depart, je voulais mettre const_iterator pour la version specialisee. Sauf que cela prend tout le temps en compte la version de base pour un appel du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print(v.begin(), v.end());
    - Pourquoi est-ce la version iterator de begin() qui est utilisee ?
    - Comment aussi signifier au niveau de la declaration template qu'on n'accepte que les const iterators ?

  2. #2
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 545
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 545
    Par défaut
    Bonjour
    Citation Envoyé par mailaka Voir le message
    J'obtiens sous VC++ error LNK2005 (already defined) et fatal error LNK1169: one or more multiply defined symbols found
    à partir du moment ou vôtre print spécialisé est défini non inline dans votre fichier d'en-tête et que celui-ci est inclue dans plusieurs fichiers vous aurez autant de définitions que d'inclusions, d'ou l'erreur. La solution 1- Rajouter inline est donc la bonne

    Ce problème n'existe pas pour la définition non spécialisée car son 'instantiation' est totalement gérée par le compilateur, celui-ci se débrouille donc à la fois pour que les définitions nécessaires existent et cela qu'une fois.

    Au depart, je voulais mettre const_iterator pour la version specialisee. Sauf que cela prend tout le temps en compte la version de base pour un appel du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print(v.begin(), v.end());
    si le vecteur n'est pas const alors begin() et end() retournent un iterator et non un const_iterator => appel de la version non spécialisée

    si votre vecteur est const alors c'est la version spécialisée qui sera appelée (utilisant const_iterator)

    - Comment aussi signifier au niveau de la declaration template qu'on n'accepte que les const iterators ?
    si c'est au niveau de la version spécialisée il suffit de remplacer les 3 iterator par const_iterator

    par contre utiliser template <typename InputIt> void print(const InputIt first, const InputIt last)... ne marche évidemment pas car const_iterator n'est pas const iterator (le const ne s'applique pas à l'itérateur lui-même)
    Bruno Pagès, auteur de Bouml (freeware), mes tutoriels sur DVP (vieux, non à jour )

    N'oubliez pas de consulter les FAQ UML et les cours et tutoriels UML

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 57
    Par défaut
    Citation Envoyé par bruno_pages Voir le message
    Bonjour


    à partir du moment ou vôtre print spécialisé est défini non inline dans votre fichier d'en-tête et que celui-ci est inclue dans plusieurs fichiers vous aurez autant de définitions que d'inclusions, d'ou l'erreur. La solution 1- Rajouter inline est donc la bonne
    Ok. Mais c'est con quand meme que meme dans une FAQ reconnue, les exemples induisent en erreur.

    si c'est au niveau de la version spécialisée il suffit de remplacer les 3 iterator par const_iterator

    par contre utiliser template <typename InputIt> void print(const InputIt first, const InputIt last)... ne marche évidemment pas car const_iterator n'est pas const iterator (le const ne s'applique pas à l'itérateur lui-même)
    Justement, comment signaler que pour ce print generique, on veut un match sur les const iterator ?

Discussions similaires

  1. specialisation partielle de template recursif
    Par damiengif dans le forum C++
    Réponses: 7
    Dernier message: 01/09/2012, 17h02
  2. [Template] specialisation de classe template
    Par vandamme dans le forum Langage
    Réponses: 3
    Dernier message: 19/10/2008, 14h22
  3. specialisation de fonction template
    Par chubinou dans le forum Langage
    Réponses: 8
    Dernier message: 13/11/2007, 14h03
  4. Réponses: 5
    Dernier message: 29/12/2005, 21h27
  5. [phpBB] Function avec le Template phpBB
    Par mangafan dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 5
    Dernier message: 27/09/2005, 16h32

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