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 :

class template avec paramètre template par défaut : erreur de link


Sujet :

Langage C++

  1. #1
    Nouveau membre du Club
    Inscrit en
    Juin 2005
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 36
    Points : 28
    Points
    28
    Par défaut class template avec paramètre template par défaut : erreur de link
    Bien le bonjour !

    Depuis que j'ai ajouté un paramètre template à l'une de mes classes - avec valeur par défaut - mon code ne link plus

    Le problème étant assez complexe et impliquant pas mal de classes dans différents fichiers, je préfère ne pas mettre ici le code exact mais plutôt une version représentative. Après plusieures heures à chercher l'origine du problème, je m'en remet à vous en espérant que quelqu'un arrive déjà à comprendre les explications qui suivent, je me lance ;

    Les différentes classes :

    - Ici, le parametre policy est le nouveau paramètre cité plus haut :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    <template class T, class policy = DefaultPolicy<T> >
    class SharedPtr
    {<div style="margin-left:40px">// ...
    SharedPtr( const SharedPtr<T, policy>& other )
    {<div style="margin-left:40px">// ...</div>}
    // ...</div>}
    - Ici, la classe de base contenant les méthodes citées dans les erreurs de link
    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
     
    // fichier .h
    typedef SharedPtr<Node> NodePtr;
     
    class Node
    {
    <div style="margin-left:40px">
    // ...
    void AddNode( NodePtr& node );
    void RemoveNode( NodePtr& node );
    // ...</div>}
     
    // fichier .cpp
    void Node::AddNode( NodePtr& node )
    {<div style="margin-left:40px">// ...</div>}
    void Node::RemoveNode( NodePtr& node )
    {<div style="margin-left:40px">// ...</div>}
    - pour finir, j'ai 2 classes qui dérivent de ce node, et lors de l'édition de liens de celles-ci, j'ai droit à des error LNK2001 décrivant les méthodes de la class Node ci-dessus (addnode et removenode). Je précise qu'il s'agit d'un héritage simple et public et que les méthodes sus-citées n'y sont pas surchargées.

    Voilà, je crois que c'est à peu près tout, j'espère ne rien avoir oublié. Tiens, une chose ; j'ai essayé de compiler sans les 2 classes héritant de Node, et là bien sûr aucun problème, ca compile, link et run

  2. #2
    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 : 42
    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
    Vu le code que tu nous donnes, c'est normal, il n'y a pas de corps à ces 2 fonctions.

  3. #3
    Nouveau membre du Club
    Inscrit en
    Juin 2005
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 36
    Points : 28
    Points
    28
    Par défaut
    Oui, en fait dans mon code il y en a un de corps (dans le cpp), là c'est juste une version simplifiée de mon code, j'edit tout de même mon message au cas où

  4. #4
    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 : 42
    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
    T'es bien sûr de compiler ce fichier cpp ?

  5. #5
    Nouveau membre du Club
    Inscrit en
    Juin 2005
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 36
    Points : 28
    Points
    28
    Par défaut
    Hum, c'est pas con ça

    Là je suis pas chez moi et n'ai donc pas accès au code, je vérifierai tout ça d'ici ce soir ou demain au pire, merci pour la piste en tout cas , je passerai dire si j'ai du neuf

  6. #6
    Nouveau membre du Club
    Inscrit en
    Juin 2005
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 36
    Points : 28
    Points
    28
    Par défaut
    Citation Envoyé par vinny_the_true
    Hum, c'est pas con ça

    Là je suis pas chez moi et n'ai donc pas accès au code, je vérifierai tout ça d'ici ce soir ou demain au pire, merci pour la piste en tout cas , je passerai dire si j'ai du neuf
    Heu, 2 secondes, il est un peu tôt et je crois bien avoir laissé mon double maléfique et ignare s'emparer de moi, il en a profité pour raconter n'importe quoi

    Je suis sous Visual 2005, existe-t-il une raison pour qu'un cpp faisant partie du projet ne soit pas compilé ? Et il faut quand même que j'eclaircisse un point : le code fonctionnait et linkait parfaitement avant que j'ajoute le paramètre template à valeur par défaut à mes SharedPtr, avec exactement le même code client qui utilise donc ces différentes -plus quelques autres- classes.
    En fait le but de la valeur par défaut du nouveau paramètre était également de ne pas modifier le code déjà existant usant des SharedPtr, ce que j'ai fais, les 3 classes Node et ses 2 descendants n'ont donc pas changé d'un poil...

    Maintenant, le problème vient peut-être d'ailleurs, si personne n'a de piste avec ce que je fourni ici je peux toujours essayer en donnant mon code à l'identique, mais ça fera rapidement un volume conséquant pour un post de forum

  7. #7
    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 : 42
    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
    C'est quoi exactement l'erreur de liens ?
    Pour mettre du code, tu peux aussi le mettre en pièce jointe

    Où déclares-tu ta politique ? Dans un autre fichier .h ? Est-ce qu'il est protégé par des #ifndef différent des autres en-têtes ?

  8. #8
    Nouveau membre du Club
    Inscrit en
    Juin 2005
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 36
    Points : 28
    Points
    28
    Par défaut
    La classe DefaultPolicy<T> est déclarée dans le header du SharedPtr, dans un namespace anonyme, au départ j'ai également pensé à un problème de ce côté là, j'ai donc essayé de la sortir de ce namespace, même résultat

    L'erreur c'est la LNK2001 "unresolved external symbol", si tu veux je collerai la "vraie" erreur avec la méthode réelle et sa décoration sitôt rentré chez moi

  9. #9
    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 : 42
    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
    Ca serait mieux avec la décoration complète, on verra peut-être qqch

  10. #10
    Nouveau membre du Club
    Inscrit en
    Juin 2005
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 36
    Points : 28
    Points
    28
    Par défaut
    Alors, voilà les différentes erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    coreengine.lib(Entity.obj) : error LNK2001: unresolved external symbol "public: virtual void __thiscall FreakEngine::SceneNode::AddNode(class Frools::SharedPtr<class FreakEngine::SceneNode,class Frools::`anonymous namespace'::BasicSharedPtrHandler<class FreakEngine::SceneNode> > &)" (?AddNode@SceneNode@FreakEngine@@UAEXAAV?$SharedPtr@VSceneNode@FreakEngine@@V?$BasicSharedPtrHandler@VSceneNode@FreakEngine@@@?A0x2a11028f@Frools@@@Frools@@@Z)
    coreengine.lib(Entity.obj) : error LNK2001: unresolved external symbol "public: virtual void __thiscall FreakEngine::SceneNode::RemoveNode(class Frools::SharedPtr<class FreakEngine::SceneNode,class Frools::`anonymous namespace'::BasicSharedPtrHandler<class FreakEngine::SceneNode> > &)" (?RemoveNode@SceneNode@FreakEngine@@UAEXAAV?$SharedPtr@VSceneNode@FreakEngine@@V?$BasicSharedPtrHandler@VSceneNode@FreakEngine@@@?A0x2a11028f@Frools@@@Frools@@@Z)
    coreengine.lib(Camera.obj) : error LNK2001: unresolved external symbol "public: virtual void __thiscall FreakEngine::SceneNode::AddNode(class Frools::SharedPtr<class FreakEngine::SceneNode,class Frools::`anonymous namespace'::BasicSharedPtrHandler<class FreakEngine::SceneNode> > &)" (?AddNode@SceneNode@FreakEngine@@UAEXAAV?$SharedPtr@VSceneNode@FreakEngine@@V?$BasicSharedPtrHandler@VSceneNode@FreakEngine@@@?A0xe836c7e8@Frools@@@Frools@@@Z)
    coreengine.lib(Camera.obj) : error LNK2001: unresolved external symbol "public: virtual void __thiscall FreakEngine::SceneNode::RemoveNode(class Frools::SharedPtr<class FreakEngine::SceneNode,class Frools::`anonymous namespace'::BasicSharedPtrHandler<class FreakEngine::SceneNode> > &)" (?RemoveNode@SceneNode@FreakEngine@@UAEXAAV?$SharedPtr@VSceneNode@FreakEngine@@V?$BasicSharedPtrHandler@VSceneNode@FreakEngine@@@?A0xe836c7e8@Frools@@@Frools@@@Z)
    Bien sûr, Camera et Entity sont les 2 classes dérivant de Node (SceneNode dans le "vrai" code). Sur ce je vais me coucher en espérant être plus inspiré demain

    Merci Miles en tout cas pour ton intérêt

  11. #11
    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 : 42
    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
    A priori, tu as un problème avec ton cpp qui soit n'est pas compilé, soit ne déclare pas les bonnes fonctions.

  12. #12
    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
    Pour être sur, tu peux toujours compiler à part ton fichier problématique, afin de localiser le problème ensuite.
    Car c'est vrai qu'on dirait bien qu'il n'a pas été compilé, ou bien que la déclaration de la fonction est différente de celle qui est dans le cpp compilé/ou non.

  13. #13
    Nouveau membre du Club
    Inscrit en
    Juin 2005
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 36
    Points : 28
    Points
    28
    Par défaut
    Alp >> Heu, je m'y prends comment pour compiler ça séparément ??

    En regardant le log de build d'un peu plus près, j'ai peut-être des infos intéressantes :

    - la solution contient 3 projets ;
    Frools qui contient SharedPtr, aucune dépendance
    CoreEngine qui contient SceneNode, Camera dépendant de Frools
    EngineTest dépendant de CoreEngine qui ne contient presque rien (le code pour lancer le moteur on s'en sera douté)

    - lors de la compil de CoreEngine, je vois bien apparaître les fichiers SceneNode, Camera et Entity comme compilés, ce projet compile et link en fait sans erreur.

    - les lib externes (dx9 et 3dsftk) me font des warnings "no public symbols found" en debug qui se transforment en erreur de link dans le projet suivant qui instancie les classes les utilisant.

    - ces différents problèmes de link apparaissent lors de la compil de EngineTest si CoreEngine est en static lib et lors de celle de CoreEngine si en dll, ce qui paraît somme toute normal...

    Peut-être ai-je tout simplement mal configuré mes projets ? (pour rappel je suis sous VS 2005) Je vais un peu chercher de ce côté là en attendant (même si je ne suis pas vraiment une bête la-dedans )

  14. #14
    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
    Pour compiler qu'un fichier, tu click droit sur le fichier > Compile.
    si tu vois des erreurs ou quoi, c'est que c'était ça.
    Si ca compile, c'était bon, et on est pas avancé.
    Vérifies que la signature de la fonction est la même dans la déclaration et dans l'implémentation etc...

  15. #15
    Nouveau membre du Club
    Inscrit en
    Juin 2005
    Messages
    36
    Détails du profil
    Informations forums :
    Inscription : Juin 2005
    Messages : 36
    Points : 28
    Points
    28
    Par défaut
    Hum, j'ai testé les compils séparées, aucun souci pour l'ensemble des fichiers ou presque...

    En fait j'ai testé enfin quelque choe avec succèe, je n'y avais même pas pensé ; j'ai tout simplement déplacé le corps des méthodes dans le .h (AddNode et RemoveNode de SceneNode tiennent maintenant entièrement dans le header). Et bien, là ça link sans problème et le programme se lance

    J'ai donc une "solution", malheureusement elle est tout sauf élégante et je ne comprends toujours pas ce qui se passe

  16. #16
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 282
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 282
    Points : 11 036
    Points
    11 036
    Par défaut

    Tu as regardé la FAQ ? Vu quelques phrases que j'ai vu ici, j'ai l'impression que les définitions (!= déclarations) de tes fonctions génériques) ne sont pas incluses comme il se devrait -- VC ne supporte pas export pour les templates.

Discussions similaires

  1. Trier dans un template avec paramètres
    Par stujava dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 23/02/2010, 09h03
  2. Réponses: 19
    Dernier message: 23/12/2009, 20h22
  3. template, itérateurs et argument par défaut de fonction
    Par goran kajfes dans le forum Langage
    Réponses: 5
    Dernier message: 24/05/2009, 19h00
  4. Réponses: 2
    Dernier message: 27/03/2009, 23h01
  5. Problème de map avec paramètre template
    Par bouba dans le forum Langage
    Réponses: 5
    Dernier message: 11/05/2007, 14h19

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