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 :

problème de spécialisation template


Sujet :

Langage C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut problème de spécialisation template
    Bonjour à tous, j'ai une fonction template que j'ai spécialisé, mes fonctions sont regroupées dans un fichier "TemplateFunction.h" :
    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
    #ifndef TEMPLATE_FUNCTION_H
    #define TEMPLATE_FUNCTION_H
     
    #include <string>
    #include <iostream>
     
    template<typename T> void f(T& elt)
    {
    	std::cout << elt << std::endl;
    }
     
    template<> void f<int>(int& elt)
    {
    	std::cout << "je suis un int " << elt << std::endl;
    }
     
    template<> void f<std::string>(std::string& elt)
    {
    	std::cout << "je suis une string " << elt << std::endl;
    }
     
    #endif
    J'ai ensuite deux classes qui utilisent ces fonctions:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #ifndef CLASSA_H
    #define CLASSA_H
     
    struct ClassA
    {
    	int val;
     
    	void methode();
    };
     
    #endif
    avec le cpp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #include "ClassA.h"
    #include "TemplateFunction.h"
     
    void ClassA::methode()
    {
    	f<int>(val);
    }
    et la classe B:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #ifndef CLASSB_H
    #define CLASSB_H
     
    #include <string>
     
    struct ClassB
    {
    	std::string val;
     
    	void methode();
    };
     
    #endif
    avec son cpp:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #include "ClassB.h"
    #include "TemplateFunction.h"
     
    void ClassB::methode()
    {
    	f<std::string>(val);
    }
    jusque là rien de très compliqué, le seul truc c'est que lorsque dans mon main je fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <iostream>
    int main()
    {
    	ClassA a;
    	ClassB b;
    	a.val = 10;
    	b.val = "toto";
    	a.methode();
    	b.methode();
    	return 0;
    }
    J'ai l'erreur de compilation suivante:
    ClassA.obj : error LNK2005: "void __cdecl f<int>(int &)" (??$f@H@@YAXAAH@Z) déjà défini(e) dans main.obj
    J'ai vérifié que si je met le corps des méthodes dans le .h (et en virant les cpp), ça compile, le truc c'est que je vois pas pourquoi lorsque c'est dans les cpp le compilo râle. (PS: j'utilise VS2003)

  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
    Tu as regardé dans la FAQ la Q/R sur les problèmes de reconnaissance des templates à l'édition des liens ?

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut
    Oui mais justement, dans mon cas, les classes A et B ne sont pas template et ne possèdent pas de méthode template, elles ne devraient donc pas rentrer dans le cas de figure abordé par la FAQ. Mes fonctions templates (celles dans TemplateFunction.h) sont bien déclarées et définies dans le même fichier .h

  4. #4
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Points : 641
    Points
    641
    Par défaut
    Et en appelant tes fonctions tout simplement comme cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void ClassA::methode()
    {
    	f(val);
    }

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut
    non j'ai toujours le même message à la compilation

  6. #6
    Membre éclairé

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Points : 858
    Points
    858
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template<> inline void f<int>(int& elt)
    {
    	std::cout << "je suis un int " << elt << std::endl;
    }

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut
    Trop bien, ça compile! Merci! Par contre, peux tu m'expliquer pourquoi on doit spécifier que la fonction doit être inline?

  8. #8
    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
    Bien vu Sylvain.

    La fonction doit être inline car sinon son code ne remplacera pas l'appel à f qui va bien et l'édition des liens sera capricieuse, comme expliqué dans l'entrée de FAQ.

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    301
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 301
    Points : 345
    Points
    345
    Par défaut
    Ok à tous

  10. #10
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Citation Envoyé par Alp Voir le message
    Bien vu Sylvain.

    La fonction doit être inline car sinon son code ne remplacera pas l'appel à f qui va bien et l'édition des liens sera capricieuse, comme expliqué dans l'entrée de FAQ.
    Je vois ça différemment. Dans les deux unités de compilation, il y a cette fonction car elle a été définie dans un en-tête (ce qu'on ne fait jamais normalement ! f<int> n'est pas une fonction template, c'est une fonction comme ClassA::methode). Il aurait fallu :
    - mettre un prototype
    - écrire le corps de al fonction dans un .cpp
    Dans ce cas-là, aucun souci de multiple définitions. Le mot-clé inline ne fait que corriger une erreur en n'exposant jamais cette fonction à l'extérieur de l'unité de compilation.

  11. #11
    Membre averti Avatar de Flo.
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2002
    Messages : 379
    Points : 404
    Points
    404
    Par défaut
    Bonjour,

    je rencontre un problème similaire.

    J'avais ouvert une discussion à ce sujet

    http://www.developpez.net/forums/d10...pecialisation/

    La discussion m'avait permis de résoudre mon problème mais sous Visual Studio 2008 uniquement et sans l'aide de "inline". Par contre avec mingw, sans inline il me fait le coup de la redéfinition. Et je ne veux pas utiliser inline.

    Quand tu (Matthieu Brucher) dis "mettre un prototype", ça signifie quoi exactement ? Il faut le mettre dans la classe, hors de la classe dans le namespace ? Peux-tu préciser s'il te plaît.

    J'ai essayé un peu tout et à chaque fois j'obtiens :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    "error: specialization of [nom de la fonction spécialisée] after instantiation"
    A noter que dans le .h associé je fais une instanciation explicite pour certaines valeurs des arguments du template (pour des raisons décrites dans la discussion citée précédemment).

    Merci

    Flo.

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

Discussions similaires

  1. Problème de spécialisation de fonction template membre
    Par Davidbrcz dans le forum Langage
    Réponses: 4
    Dernier message: 29/12/2007, 21h01
  2. Problème de spécialisation de fonction membres template
    Par ludovic.barrillie dans le forum Langage
    Réponses: 3
    Dernier message: 17/04/2007, 09h44
  3. Problème std::list + templates GCC/G++ 4.x
    Par Amalsek dans le forum GCC
    Réponses: 5
    Dernier message: 12/05/2006, 12h04
  4. Problème de compilation template
    Par Bourrine dans le forum Langage
    Réponses: 4
    Dernier message: 20/01/2006, 22h15
  5. [XSLT] Problème avec apply-templates
    Par NeoMan dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 29/12/2005, 15h45

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