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 :

Fonctions template : séparation prototype/déclaration dans .h ?


Sujet :

C++

  1. #1
    Membre éclairé
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Par défaut Fonctions template : séparation prototype/déclaration dans .h ?
    Bonjour à tous.

    Petite question de débutant concernant les templates.
    J'ai cru comprendre en effet qu'il ne fallait pas déclarer une fonction template dans un .cpp pour éviter de s'exposer à des risques inutiles.
    Cependant, peut-on séparer le prototype de la déclaration d'une fonction template dans un .h ou c'est également dangereux ? (je précise que c'est uniquement par souci de lisibilité quand j'ai un grand nombre de fonctions)

    Genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    namespace mon_espace{
    template<typename T> T ma_fonction(T ma_variable);
    }
     
    template<typename T> T mon_espace::ma_fonction(T ma_variable)
    {
    (blablabla...)
    }

  2. #2
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Tu es tout à fait libre de séparer la déclaration de la définition d'une classe ou d'une fonction générique à l'instar d'une classe ou d'une fonction non générique. Cf ici par exemple.

    La problématique exposée par exemple dans l'entrée de la F.A.Q. Pourquoi mes templates ne sont-ils pas reconnus à l'édition des liens ? est lié à la compilation séparée et au fait qu'un générique n'est réellement défini qu'au moment de son utilisation.

  3. #3
    Membre éclairé
    Homme Profil pro
    Doctorant en Astrophysique
    Inscrit en
    Mars 2009
    Messages
    312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Astrophysique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2009
    Messages : 312
    Par défaut
    J'avais bien lu la FAQ, mais j'avais zappé le :
    #include "exemple.tpp" // <-- astuce ici !!!
    Merci 3DArchi

  4. #4
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 635
    Par défaut
    Salut,

    Tu peux, cependant, trouver un "work arround" au problème, si tu connais par avance les types qui seront réellement utilisés par tes classes et fonctions templates, dans ce que l'on appelle l'instanciation explicite.

    Tu peux, en effet, envisager de travailler avec trois (voir quatre) fichiers séparés sous une forme proche de
    MyClass_def.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
    /** Ce fichier ne contient que la déclaration de la classe et de ses fonctions 
      * membres, c'est à dire, tout ce que le compilateur doit connaitre au
      * moment où il rencontre une déclaration de variable
      */
    #ifndef MYCLASS_DEF_HPP
    #define MYCLASS_DEF_HPP
    template <typename T/*, ...*/>
    class MyClass
    {
        public:
            MyClass(T t);
            T foo();
            /* tout ce dont tu as besoin */
        private:
           T t_;
    };
    #endif // MYCLASS_DEF_HPP
    MyClass.impl
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    /* ce fichier contient l'implémentation des différentes fonctions de la classe
     *
     * il correspondrait au fichier .tpp de l'exemple
     */
    template <typename T>
    MyClass<T>::MyClass<T const & t):t_(t){}
    template <typename T>
    inline void MyClass<T>::foo()
    {
        /* ce qui doit être fait */
    }
    MyClass_inst.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
    #include "MyClass_def.hpp"
    #include "MyClass.impl"
    /* Dans ce fichier, nous forçons à la génération du code binaire pour
     * différents types dont nous savons que la classe sera utilisée avec
     */
    /* nous savons que la classe sera utilisée avec des (signed) int */
    template class MyClass<int>;
    /* ainsi qu'avec de unsigned long long */
    template class MyClass<unsigned long long> ;
    /* des types personnalisés peuvent parfaitement être introduits 
     * penser à inclure les en-têtes correspondantes
     */
    template class MyClass<UnTypePersonnalise>;
    /* voire même des types template personnalisés */
    template class MyClass< MonTypeTemplate<int> >;
    /* en version C++1x : */
    template class MyClass< MonTypeTemplate<int>>;
    Enfin, il peut être utile de prévoir, malgré tout, un dernier fichier pour tous les types auxquels nous n'aurions pas pensés (et qui ne seront donc pas instanciés explicitement)
    MyClass.hpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    #ifndef MYCLASS_HPP
    #define MYCLASS_HPP
    #include "MyClass_def.hpp"
    #include "MyClass.impl"
    #endif // MYCLASS_HPP
    Pour tous les types instanciés implicitement (donc, a priori, tous ceux de ton projet, vu que tu saura que tu peux instancier explicitement ta classe pour des types donnés), tels que, selon mon exemple, int, unsigned long long, UnTypePersonnalise et MonTypeTemplate<int>, tu pourras inclure sans risque le seul fichier MyClass_def.hpp.

    Si ta classe est réutilisée par quelqu'un d'autre, ou, du moins, avec un type qui n'a pas encore été instancié de manière explicite, il s'agira d'inclure MyClass.hpp

    NOTA: j'ai choisi la facilité en instanciant de manière explicite l'ensemble de la classe, mais il est possible (sous condition toutefois) de n'instancier que certaines fonctions particulières de celle-ci
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

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

Discussions similaires

  1. Syntaxe fonction template dans classe template
    Par Aleph69 dans le forum C++
    Réponses: 6
    Dernier message: 15/07/2011, 15h32
  2. Spécialisation de fonction template dans une class template
    Par summerstorm dans le forum Langage
    Réponses: 6
    Dernier message: 05/01/2010, 20h15
  3. Fonction template dans une classe template
    Par mister3957 dans le forum Langage
    Réponses: 9
    Dernier message: 08/07/2008, 12h11
  4. [Fonction template]Déclaration invalide
    Par khazna dans le forum C++
    Réponses: 0
    Dernier message: 03/03/2008, 20h30
  5. Déclarer une fonction ayant 2 prototypes dans une DLL
    Par Jayceblaster dans le forum Delphi
    Réponses: 8
    Dernier message: 17/02/2007, 12h00

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