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 :

probleme avec tamplate


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Décembre 2005
    Messages
    180
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 180
    Par défaut probleme avec tamplate
    bonjour!
    j ai un petit probleme avec les temnplates!

    je cre une classe node dans un fichier .H

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    template<class T>
    class node
    {
    public:
    void print();
    private:
    T data;
    };
    et ensuite je veux ecrire le code de la fonction dans un fichier .CPP

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template<class T>
    void node<T>::print()
    {
    cout<<data;
    }
    mais ca ne marche pas!!

    par contre si je met toute la fonction dans le fichier .h tout marche bien!

  2. #2
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut
    La norme du c++ spécifie que l'on peut définir le coeur des fonctions membres templates dans le fichier cpp, en utilisant un mot clef dont je ne me souvient plus.

    Cependant je ne connais pas un compilateur qui, au dernière de mes nouvelles, gère cet aspect de la norme.

    Du coup on est obligé d'écrire le code dans les .h.

    C'est trés embétant dans le cas de l'écriture d'un bibliothèque.


    Personelement je ne les utilises plus, car il est quasiment toujours possible d'utiliser l'héritage pour régler ce genre de problème et c'est beaucoup plus digne de l'utilisation d'un langage objet.

  3. #3
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut
    D'ailleurs la faq c++ donne une astuce plus ou moins "propre" pour quand même définir les fonctions dans le cpp.
    De toute façon ça ne fonctionnera toujours pas bien pour la diffusion d'une bibliothèque en séparant bien les .h des .cpp.

  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
    Citation Envoyé par MatRem
    La norme du c++ spécifie que l'on peut définir le coeur des fonctions membres templates dans le fichier cpp, en utilisant un mot clef dont je ne me souvient plus.
    export. Voir http://www.bourguet.org/cpp/export.pdf par exemple.

    Cependant je ne connais pas un compilateur qui, au dernière de mes nouvelles, gère cet aspect de la norme.
    como, intel

    Du coup on est obligé d'écrire le code dans les .h.

    C'est trés embétant dans le cas de l'écriture d'un bibliothèque.
    Si j'ai bien deviné la source de ton embêtement, export n'est ni nécessaire ni suffisant pour résoudre ce problème. Voir le lien que j'ai donné. Le modèle de généricité qu'ajoute C++/CLI est vraissemblablement une meilleure solution; mais je ne suis pas convaincu du tout de l'intérêt d'ajouter au C++ un nouveau modèle objet et un nouveau modèle de généricité (quant à la manière dont C++/CLI le fait, je ne suis pas sûr du tout non plus que c'était la meilleure manière de le faire).

    Personelement je ne les utilises plus, car il est quasiment toujours possible d'utiliser l'héritage pour régler ce genre de problème et c'est beaucoup plus digne de l'utilisation d'un langage objet.
    Tu me réécris std::list et std::find à base d'héritage et tu m'expliques en quoi c'est meilleur?

    Quant à la dignité, ce n'est pas un concept que j'utilise quand je programme et je ne vois pas en quoi une forme de polymorphisme est plus digne qu'une autre.

  5. #5
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut
    C'est tout simplement meilleur puisque les templates ne sont pas toujours trés bien géré.
    Du moins par g++ que j'utilise (et visual c++ que j'utilisais).

    Quand à la dignité, j'aurais pu trouver un autre mot, mais je pense que les templates sont une surcouches qui n'est pas forcément utile, et que je n'arrive pas trés bien à les intégrer dans un concept objet.
    D'ailleurs en java (purement objet), point besoin de template pour gérer les listes ou autres conteneurs.

  6. #6
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par MatRem
    C'est tout simplement meilleur puisque les templates ne sont pas toujours trés bien géré.
    Du moins par g++ que j'utilise (et visual c++ que j'utilisais).
    Tu as des exemples de mauvaise gestion des templates qui font qu'une liste à base d'héritage (que j'attends toujours de voir) est meilleure qu'une liste à base de template? Quand on voit ce que certains font avec les templates (mot clé pour une recherche: metaprogrammation), je doute fort que cette d'application paradigmatique de la programmation générique pose des problèmes. Je n'en ai en tout cas pas rencontré.

    Quand à la dignité, j'aurais pu trouver un autre mot, mais je pense que les templates sont une surcouches qui n'est pas forcément utile,
    C'est vrai que la vérification statique des types est inutile... quand je veux un langage à typage dynamique -- ce qui m'arrive -- je sais où les chercher.

    La programmation générique est un des 3 types de programmations supportées par le C++ (les deux autres étant la programmation impérative et la programmation OO, ceux qui ne le sont pas sont la programmation fonctionnelle et la programmation logique) et n'est pas une surcouche plus que le modèle objet du C++ est une surcouche de sa couche impérative.

    et que je n'arrive pas trés bien à les intégrer dans un concept objet.
    Si ça ne correspond pas à tes problèmes rien ne te force à l'utiliser. Mais de là à écrire que c'est inutile il vaut plus d'arguments.

    D'ailleurs en java (purement objet), point besoin de template pour gérer les listes ou autres conteneurs.
    C'est donc parce que le langage n'en avait pas besoin qu'ils ont été ajouté :-)

  7. #7
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut
    Tu as des exemples de mauvaise gestion des templates
    C'est ce que j'ai dit avant, certain compilateur ne gère pas leur définition dans un .cpp.

    une liste à base d'héritage (que j'attends toujours de voir) est meilleure qu'une liste à base de template
    Je sais pas ce que tu entends par meilleur mais en tout cas il n'y aura pas le problème des templates.
    En fait je me suis trompé en disant que java n'utilise pas de template, il utilise des choses équivalente. Par contre cela me semble tout à fait réalisable.

    Arrête moi si je me trompe, mais on utiliserait une classe de base Contenable, les listes stockerai donc des pointeurs de contenable.Et ensuite on pourrait y ajouter des (new Integer) par exemple si Integer dérive de Contenable.

    le modèle objet du C++ est une surcouche de sa couche impérative.
    Je suis d'accord et je pense même que c'est dommage que il n'y est pas eu carément un nouveau langage Objet, même si l'idée d'ajouter cette couche au C est bonne.

    Si ça ne correspond pas à tes problèmes rien ne te force à l'utiliser.
    Justement c'est ce qui fait que je trouve qu'il est possible de s'en passer (je ne dis pas qu'il est complétement inutile).

    D'ailleurs en java (purement objet), point besoin de template pour gérer les listes ou autres conteneurs.
    En fait à peu prés le même système est utilisé, j'ai l'impression...

  8. #8
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    Si j'ai bien compris, la liste à base de templates est plus performante que celle à base d'héritage (mais pas de beaucoup : sur une grosse machine actuelle, ça ne doit même pas se voir. Par contre, sur un systême embarqué...).
    Mais à moins que je me trompe, il ne faut pas s'imaginer qu'il n'y a rien "à base d'héritage" dans les conteneurs de la STL: Toute la partie "interface et héritage" se trouve dans les itérateurs (C'est pourquoi les algorithmes marchent dessus et non directement sur les conteneurs).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par MatRem
    Tu as des exemples de mauvaise gestion des templates
    C'est ce que j'ai dit avant, certain compilateur ne gère pas leur définition dans un .cpp.
    Quels problemes cela te pose-t'il pour que tu preferes la solution a base d'heritage? As-tu verifie que le fait de pouvoir utiliser le modele de compilation separee serait reellement une solution a ces problemes?

    une liste à base d'héritage (que j'attends toujours de voir) est meilleure qu'une liste à base de template
    Je sais pas ce que tu entends par meilleur mais en tout cas il n'y aura pas le problème des templates.

    Arrête moi si je me trompe, mais on utiliserait une classe de base Contenable, les listes stockerai donc des pointeurs de contenable.Et ensuite on pourrait y ajouter des (new Integer) par exemple si Integer dérive de Contenable.
    Ce que j'entends pas meilleur? Rien de particulier, je suis a la recherche des raisons que font que tu preferes l'heritage pour quelque chose comme des listes.

    A part l'inconveniant esthetique d'avoir besoin de la definition, je ne vois toujours pas ce que tu reproches a l'utilisation du modele d'inclusion qui n'est pas present dans le modele separe(1). Mais je peux te dire ce que je reproche a ta technique:
    • absence de verification statique des types
    • impossibilite sans definir des wrappers d'y mettre des objets non prevus pour; si on definit un nouveau type qui n'a aucune raison d'avoir des membres virtuels, on se retrouve soit a devoir en definir pour fournir l'interface, soit a devoir utiliser un wrapper quand on a besoin d'une liste de ces objets.
    • surcout en memoire (on a des listes de pointeurs quand on pourrait avoir des listes d'objet)
    • surcout en CPU


    le modèle objet du C++ est une surcouche de sa couche impérative.
    Je suis d'accord
    Tu me fais dire plus que ce que je n'ai ecrit:
    Citation Envoyé par Jean-Marc Bourguet
    La programmation générique [...] n'est pas une surcouche plus que le modèle objet du C++ est une surcouche de sa couche impérative.
    Je n'aime en particulier pas du tout les connotations negatives que le mot "surcouche" entraine alors que tu as l'air de les desirer quand tu ajoutes:
    et je pense même que c'est dommage que il n'y est pas eu carément un nouveau langage Objet, même si l'idée d'ajouter cette couche au C est bonne.
    Il y a pour moi trois facteurs qui ont fait le succes du C++:
    • il est arrive au bon moment
    • il offrait une voie de migration incrementale a partir du C
    • il n'imposait pas l'utilisation d'un 'paradigme'


    D'ailleurs en java (purement objet), point besoin de template pour gérer les listes ou autres conteneurs.
    En fait à peu prés le même système est utilisé, j'ai l'impression...
    Je n'ai jamais ecrit cela, au contraire j'ai fait allusion au fait que Java avait maintenant un modele de genericite (different de celui du C++, on peut discutter de l'interet de l'un et de l'autre mais c'est un autre sujet).

    (1) Il me semble connaitre assez bien les effets des deux modeles; cela fait deux ans que j'ai un compilateur permettant le modele de compilation separee des templates et je m'en sers. Je vois des avantages a celui-ci dans certains cas, mais les inconveniants lies a son absence sont tres loin d'etre suffisant pour moi que pour me passer des templates dans des cas cas comme les conteneurs.

  10. #10
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut
    Mon compilateur (g++) ne gère pas la compilation séparée.
    Pour la création de bibliothèque je ne trouve pas ça cool...
    L'utilisateur est obligé de se taper la compilation des parties templates, et les point h sont plus lourds.

    Ensuite pour le problème de ma gestion par héritage:
    -je ne vois en effet pas comment vérifier statiquement le type (si quelqu'un a une idée ça m'intéresse).
    -je ne comprends pas trop ton deuxième point
    - les surcouts en mémoire et en cpu je n'y crois pas... en plus travailer avec les pointeurs plutôt qu'avec les objets me semble un peu plus optimisé niveau mémoire.

    Enfin, pour la dernière citation c'est moi même que je contredis .

  11. #11
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par MatRem
    Mon compilateur (g++) ne gère pas la compilation séparée.
    Pour la création de bibliothèque je ne trouve pas ça cool...
    Je suppose que tu imagines qu'avec le modele de compilation separee des templates, le code pourra se trouver dans une bibliotheque? Desole de te decevoir, ce n'est pas le cas. Est-ce que tu as lu l'article dont j'ai donne un URL? J'y decris ce qu'on peut attendre et ce qu'il est illusoire d'attendre de export.

    Note que je peux concevoir que ce soit parfois un probleme, mais pour une liste ou de toute maniere les membres seraient tous inline et donc present dans l'entete, je n'en vois pas.

    Ensuite pour le problème de ma gestion par héritage:
    -je ne vois en effet pas comment vérifier statiquement le type (si quelqu'un a une idée ça m'intéresse).
    Je n'en connais pas.

    -je ne comprends pas trop ton deuxième point
    Pour mettre des elements dans une MatRem::List, il faut que leur classe herite de MatRem::Contenable. J'ai quelques millions de lignes de code qui ne connaissent rien du namespace MatRem, si je veux mettre les classes qu'elles utilisent dans une liste, je dois creer de nouvelles classes ou modifier les anciennes. Si ces classes proviennent d'un fournisseur externe, je n'ai pas le choix: il me faut des wrappers Ce genre de techniques est peut-etre gerable dans les langages qui les prevoient des le depart, pas en C++ pour le genre de projets sur lesquels je travaille.

    - les surcouts en mémoire et en cpu je n'y crois pas... en plus travailer avec les pointeurs plutôt qu'avec les objets me semble un peu plus optimisé niveau mémoire.
    Si je veux faire une liste d'entier, il faut que je fasse des new Integer en plus de definir la classe Integer et que je m'arrange pour que la memoire soit liberee. Cela fait un certain surcout, pour ne pas ecrire un surcout certain.

    Des qu'on a une classe a semantique de valeur, le probleme se pose. Hors les classes a semantique de valeur forment une proportion non negligeable des classes.

    Pour les classes qu'on manipule a partir d'un pointeur -- qui sont en fait celles qui correspondent le mieux a un conception OO -- la je ne vois meme pas l'interet de ton interface Contenable. Elle va definir quoi comme operations? Ce que je veux c'est mettre le pointeur (eventuellement intelligent) dans la liste. Il faut que je l'encapsule aussi?

    Enfin, pour la dernière citation c'est moi même que je contredis .
    Je sais, mais l'attribution est trompeuse.

  12. #12
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par MatRem
    -je ne vois en effet pas comment vérifier statiquement le type (si quelqu'un a une idée ça m'intéresse).
    Faire une classe d'objet liste par classe de base à mettre dans une liste, éventuellement à l'aide de macros. Par contre, tu n'arriveras pas à me convaincre que c'est mieux que d'utiliser des templates.

    Citation Envoyé par MatRem
    -je ne comprends pas trop ton deuxième point
    Comment faire une liste d'entiers, si tu ne peux faire qu'une liste d'Objet ? Soit tu définis un type spécifique ListeDEntier, soit tu écrit un objet qui dérive d'Objet et encapsule un entier, soit tu mets de la magie de compilateur pour qu'il te génére ce genre d'objet tout seul (voir boxing en Java et C#1.0).


    Citation Envoyé par MatRem
    - les surcouts en mémoire et en cpu je n'y crois pas... en plus travailer avec les pointeurs plutôt qu'avec les objets me semble un peu plus optimisé niveau mémoire.
    Ca dépend de quel type de conteneur, et surtout de quel type d'objets stockés, tu parles. Pour info, j'ai fais des tests de perfs avec un conteneur d'entier en C# 1.0 (sans générics) et en C#2.0 (avec générics), avec un rapport 5 en faveur du second (1). Je suis convaincu que pour des objets lourds, la situation pourrait évoluer.



    Ces seuls points ont suffit à faire modifier deux langages : adopter les generiques dans Java et les generics dans C# (qui ne sont pas le même modèle de génériques, en passant). Rien que ça laisse à entendre qu'il y a une raison.


    (1) Bien entendu, la maxime veut qu'il ne faile pas croire un test de perfs que l'on n'a pas truqué soi-même.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  13. #13
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut
    Je crois que le plus simple c'est que j'essaye de coder tout ça, et je fasse des petits comparatifs mémoire/temps/cpu.

    Si jamais j'arrive à quelquechose d'intéressant je reviendrais l'exposer.

    J'ai enregistré ton lien (Jean Marc), je vais le lire à têtes reposé.

  14. #14
    Membre émérite Avatar de MatRem
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    750
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 750
    Par défaut
    Bon je suis arrivé à une première mouture de List à base d'héritage.
    Je n'ai, pour l'instant, réalisé que la liste simplement chainée.
    Cependant j'espère pouvoir l'améliorer car le fixage du type stocké se fait à l'aide des type_info. La vérification du type étant fait à l'éxécution ça doit ralentir un peu le programme client.
    Par contre il est possible de stocker tout ce qu'on veut (en n'activant pas la vérification du type stocké), et de le récupérer; à condition de savoir ce qu'on y a mit.
    Je n'ai pas encore réalisé de comparaison de performance, mais j'y compte bien.

    La bibliothéque: lien
    Un raccourci vers la doc lien

Discussions similaires

  1. Probleme avec la copie des surfaces
    Par Black_Daimond dans le forum DirectX
    Réponses: 3
    Dernier message: 09/01/2003, 10h33
  2. Problèmes avec le filtrage des ip
    Par berry dans le forum Réseau
    Réponses: 9
    Dernier message: 30/12/2002, 07h51
  3. probleme avec la touche F10
    Par b.grellee dans le forum Langage
    Réponses: 2
    Dernier message: 15/09/2002, 22h04
  4. Probleme avec fseek
    Par Bjorn dans le forum C
    Réponses: 5
    Dernier message: 04/08/2002, 07h17
  5. [Kylix] probleme avec un imagelist
    Par NicoLinux dans le forum EDI
    Réponses: 4
    Dernier message: 08/06/2002, 23h06

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