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 :

Templates et undefined references


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 165
    Points : 62
    Points
    62
    Par défaut Templates et undefined references
    Bonjour tout le monde,
    Je me permets de venir vers vous pour une question ridicule mais où je suis incapable de trouver la solution...

    J'ai actuellement une classe définie comme ceci
    socketshandler.hpp
    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
     
    #ifndef __SOCKETSHANDLER_HPP__
    # define __SOCKETSHANDLER_HPP__
     
    #  include <iostream>
     
    class   SocketsHandler
    {
    /* Variables */
    private:
    public:
        enum        TYPE { RabbitMQ };
     
    /* Methods */
    private:
     
    public:
        SocketsHandler();
        ~SocketsHandler();
     
        template <typename ...Args>
        void        addHandler(SocketsHandler::TYPE type, Args &&...args);
    };
     
    #endif // !__SOCKETSHANDLER_HPP__
    socketshandler.cpp
    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
     
    #include "socketshandler.hpp"
     
    //-----------------------------------------------------
    SocketsHandler::SocketsHandler()
    //-----------------------------------------------------
    {
    }
     
    //-----------------------------------------------------
    SocketsHandler::~SocketsHandler()
    //-----------------------------------------------------
    {
    }
     
     
    //-----------------------------------------------------
    template <typename ...Args>
    void        SocketsHandler::addHandler(SocketsHandler::TYPE type, Args &&...args)
    //-----------------------------------------------------
    {
    }
    et le main
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    #include "socketshandler.hpp"
     
    int main()
    {
     
        SocketsHandler  toto;
     
        toto.addHandler(SocketsHandler::TYPE::RabbitMQ, "Toto", "tata");
     
    }
    Le problème est que quand je compile j'obtiens le message suivant
    test.cpp.text+0x2c): undefined reference to `void SocketsHandler::addHandler<char const (&) [5], char const (&) [5]>(SocketsHandler::TYPE, char const (&) [5], char const (&) [5])'

    Ce que je ne comprends pas c'est que si je définis ma fonction "addHandler" dans mon .hpp, je n'ai pas l'erreur...
    Je n'arrive pas à voir ce que je fais de mal

    Est-ce que quelqu'un peut m'aiguiller?
    J'ai beau chercher sur les templates ou sur les variadics... je ne trouve rien qui pourrait m'aider

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    en très bref:
    la règle de base est "template XOR cpp".
    PS: comme tout conseil, on peut trouver des exceptions.

    en plus long:
    Une template n'est pas du code, mais un moyen d'indiquer au compilateur comment générer du code.
    Lorsque tu inclues un en-tête, il est copié dans le code qui l'inclue. Du coup, seul la déclaration de la template est visible.
    Au moment de générer la fonction, le compilateur à besoin de tout le code.
    Il n'y a que deux solutions possibles:
    1. placer le code de la fonction dans l'en-tête la déclarant (directement, en bas de fichier, ou dans un fichier systématiquement inclus après la déclaration)
    2. forcer l'instanciation de certaines situations, les autres étant impossibles à utiliser.

    Dans le cas présent, c'est une template variadique (qui utilise un "parameter pack", le ...), donc c'est très certainement la première solution qu'il faut choisir.

    Nous avons une entrée dans notre faq à ce sujet: Pourquoi mes templates ne sont-ils pas reconnus à l'édition des liens?


    Conclusion:
    Fais voir ton code quand tu définis la fonction dans l'en-tête?

    PS: par contre, tu cours à la catastrophe avec cette technique, ta template va être un énorme switch pas beau du tout.
    Je t'invite à placer le type de socket dans les parametres templates
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 165
    Points : 62
    Points
    62
    Par défaut
    Salut ternel,
    Tout d'abord merci pour ton retour et ton explication.

    Citation Envoyé par ternel Voir le message
    en très bref:
    Conclusion:
    Fais voir ton code quand tu définis la fonction dans l'en-tête?
    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
     
    class   SocketsHandler
    {
    /* Variables */
    private:
    public:
        enum                        TYPE { Type1 };
     
    /* Methods */
    private:
     
    public:
        SocketsHandler();
        ~SocketsHandler();
     
        template <typename ...Args>
        void        addHandler(SocketsHandler::TYPE type, Args &&...args)   {
            switch(type)    {
                case SocketsHandler::TYPE::Type1:
                     ...
                    break;
     
                default:
                    std::cout << "Not handled" << std::endl;
            };
        }
    };

    Citation Envoyé par ternel Voir le message
    PS: par contre, tu cours à la catastrophe avec cette technique, ta template va être un énorme switch pas beau du tout.
    Je t'invite à placer le type de socket dans les parametres templates
    Je ne suis pas sûr de comprendre. Tu veux dire que je devrais définir ma fonction addHandler de la forme ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        template <typename T, typename ...Args>
        void        addHandler(Args &&...args)   {
               ...
        }
    ou d'utiliser le design pattern Fabrique?

  4. #4
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    En gros, c'est dommage de créer une template pour faire un switch sur un argument.
    Ca veut dire que tu as toute la puissance des templates pour controler ce que tu appelles, et finalement, tu fais juste un "switch default throw", dans chaque fonction généré par la template.

    On en parle quand ton problème d'édition des liens sera résolu.
    Avec le code dans l'en-tête, ca devrait fonctionner.

    Si ce n'est pas le cas:
    1. As-tu activés tous les warnings (pour g++, c'est -Wall, voire -Wall -Wextra).
    2. As-tu corrigé ceux présents?
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    165
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 165
    Points : 62
    Points
    62
    Par défaut
    Yes j'ai corrigé en basculant mon code dans le .hpp mais du coup, au vue de tes explications j'ai modifié complètement mon code...

    En y réfléchissant à nouveau, je complexifiais énormément le code pour un gain qui ne me servira pas. Le polymorphisme suffira dans mon cas présent

    Encore merci pour le temps consacré.

Discussions similaires

  1. Template et "undefined reference to operator<<"
    Par coberle dans le forum C++
    Réponses: 15
    Dernier message: 19/03/2013, 09h07
  2. Réponses: 8
    Dernier message: 20/03/2011, 02h21
  3. System - Event / Template => undefined reference
    Par Whyzix dans le forum Langage
    Réponses: 8
    Dernier message: 06/04/2010, 23h18
  4. " undefined reference to " avec methode template
    Par coldrink dans le forum Langage
    Réponses: 3
    Dernier message: 24/10/2009, 20h05
  5. [Template] Templates et undefined reference
    Par FadeOut dans le forum C++
    Réponses: 9
    Dernier message: 12/12/2008, 17h04

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