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 :

Fonctions template et pointeurs


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mars 2011
    Messages : 6
    Par défaut Fonctions template et pointeurs
    Bonjour à tous!
    Tout d'abord, merci pour le forum, que je consulte de plus en plus régulièrement, et qui est une mine d'informations!

    Je poste aujourd'hui parce que j'ai un problème sur lequel je suis bloqué depuis un moment. Il s'agit de conception, et mes connaissances étant limitées en POO, je me permets de faire appel à votre aide!

    Je développe un programme ou l'utilisateur peut définir des fonctions mathématiques. Il s'agit de fonctions qui seront ensuite évaluées à l'intérieur du code. On a donc un truc dans ce gout-là :
    Code maclasse.hpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include "eval_func.tpp"
    class MaClasse
    {
    	private :
    		type2 eval_type_2(const type2&);
    		type1 eval_type_1(const type1&);	
     
    		template<class T> T eval_func(const T&);
    };

    Code eval_func.tpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #include "mafonction.tpp"
    template<class T> T MaClasse::eval_func(const T& val)
    {
    	T resultat;
    	resultat = mafonction(val);
    	return resultat;
    }
    Les fonctions "eval_type_1" et "eval_type_2" font toutes les deux appel à "eval_func", mais avec un type différent, d'où l'utilisation de "eval_func" en template.
    Les extensions .tpp désignent les fichiers de définition de fonctions template. Je crois qu'on pourrait les mettre également dans des .hpp, mais je trouve ça moins clair... Il me semble en revanche qu'on ne peut pas les mettre dans des .cpp, car on ne peut pas compiler une fonction template avant de savoir quel type sera utilisé au moment de l'appel.

    Pour le moment, à chaque fois que l'utilisateur donne une nouvelle définition pour "mafonction()", je suis obligé de recompiler "maclasse". J'aimerais changer ça.

    J'aurais aimé ne plus avoir besoin d'inclure les fichiers définissant les fonctions (.tpp) dans "maclasse.hpp", et utiliser des pointeurs de fonctions. Dans l'idéal j'aurais une fonction SetFuncPointer() dans "maclasse" qui serait utilisée dans le main :
    Code main.cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include "mafonction.tpp"
    int main()
    {
    maclasse A;
    A.SetFuncPointer(&mafonction);
     
    type1 var1;
    var1 = A.eval_type_1(var1);
     
    type1 var2;
    var2 = A.eval_type_2(var2);
    }
    Seulement, on ne peut pas utiliser de pointeurs vers des fonctions template sans donner le type d'appel... Cela m'oblige donc à créer autant de SetFuncPtr_...() que de types d'appel de la fonction concernée...

    Ma question :
    Comment supprimer mes inclusions de fichiers .tpp dans "maclasse.hpp", et les mettre dans main.cpp, afin de ne recompiler que "main.cpp" lorsque l'utilisateur modifie "mafonction()"?

    Je vous remercie d'avance pour votre aide!

  2. #2
    Membre très actif
    Homme Profil pro
    Second de cuisine
    Inscrit en
    Avril 2005
    Messages
    193
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Second de cuisine
    Secteur : Alimentation

    Informations forums :
    Inscription : Avril 2005
    Messages : 193
    Par défaut
    Pour les pointeurs de fonctions, perso j'utilise ceci:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef bool(*funcptr)();
    Dans une classe, cela donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class A
    {
        public:
            void SetCallback(funcptr fptr) { _callback = fptr; }
            bool CallBack() { return _callback(); }
        protected:
            /* callback */
            funcptr _callback;
    }
     
    function lol()
    {
            return true;
    }

    Et pour mettre ca en place

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    A* a = new A();
    a.SetCallBack(lol);
    // appel
    bool resultat = a.CallBack();

  3. #3
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mars 2011
    Messages : 6
    Par défaut
    Merci pour ta réponse!

    Malheureusement, ton exemple ne s'applique pas dans mon cas, car il s'agit de "template functions", et non de fonctions typées... D'après ce que j'ai pu lire un peu partout sur le net, et vu les messages d'erreur que j'obtiens en essayant, le C++ ne permet pas de créer un pointeur vers une "template function", sauf en spécifiant le type d'appel. Ex : a.SetCallBack(lol<double>);

    Je cherche une solution optimale pour contourner ce problème... D'autres idées?

  4. #4
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Mon mal de crâne m'empêche de bien comprendre ton problème mais peut être que les classes de politique pourrait convenir ? http://alp.developpez.com/tutoriels/traitspolicies/#LII

    En gros, cela consiste à mettre la fonction eval_func() dans une classe et à la passer en paramètre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    template<class Politique> // garde pas ce nom, c'est pour l'exemple :)
    class MaClasse
    {
       private :
          type2 eval_type_2(const type2&);
          type1 eval_type_1(const type1&);	
     
          template<class T> T eval_func(const T&) { return Politique::mafonction(val); }
    };
    (remarque : c'est bien de séparer le l'implémentation de ta classe dans un fichier séparé, mais pour des templates qui tiennent sur une ligne, ça améliore pas trop la lisibilité)

    L'utilisateur peut alors définir ses propres politiques sans avoir à modifier MaClass
    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
    #include "mafonction.tpp"
     
    class MaFonction1 {
       template<class T> static inline mafonction(T const& val) {...}
    };
     
    class MaFonction2 {
       template<class T> static inline mafonction(T const& val) {...}
    };
     
    int main()
    {
       type1 var1;
       type1 var2;
     
       MaClasse<MaFonction1> A1;
       var1 = A1.eval_type_1(var1);
       var2 = A1.eval_type_2(var2);
     
       MaClasse<MaFonction1> A2;
       var1 = A2.eval_type_1(var1);
       var2 = A2.eval_type_2(var2);
    }
    Pour aller plus loin, tu pourrais mettre également les type1 et type2 en paramètres template dans MaClass. Et du coup, ta classe MaClass ressemble beaucoup à un simple boost.apply

  5. #5
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2011
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mars 2011
    Messages : 6
    Par défaut
    Merci beaucoup, ça ressemble beaucoup plus à ce que j'attendais (même si je ne sais pas exactement quelle est la solution à mon problème).

    Je regarde ça de plus près d'ici peu, et je te redis si ça marche.

    PS : je ne sais pas non plus ce qu'est boost.apply. Je ne connais rien en Boost, et j'aimerais pouvoir m'en passer, mais je vais quand même jeter un oeil!

Discussions similaires

  1. Réponses: 3
    Dernier message: 13/10/2012, 15h02
  2. Templates et pointeurs de fonctions
    Par feda12 dans le forum C++
    Réponses: 7
    Dernier message: 09/03/2011, 10h04
  3. Pointeur de fonction, Template, map et autres joyeusetés
    Par K2R Nolween dans le forum Langage
    Réponses: 6
    Dernier message: 20/05/2009, 04h14
  4. template et pointeur de fonction.
    Par ZaaN dans le forum Langage
    Réponses: 10
    Dernier message: 11/08/2007, 08h15
  5. Pointeur sur une fonction template
    Par Progs dans le forum Langage
    Réponses: 2
    Dernier message: 15/02/2006, 20h25

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