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 :

template, pointeur de fonction et déclaration


Sujet :

Langage C++

  1. #1
    Membre habitué Avatar de mensoif
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    248
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 248
    Points : 129
    Points
    129
    Par défaut template, pointeur de fonction et déclaration
    Bonsoir,

    je tombe sur un résultat étrange lors d'utilisation de pointeur de fonction generique.

    J'utilise deux pointeurs de fonctions génériques de la forme suivante:

    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
    template<class T>
    void AVLTree<T>::Fonction(T &data) {
    	cout << "val : " << data.getA().getX() << " " 
    		 << data.getA().getY() << " " 
    		 << data.getB().getX() << " " 
    		 << data.getB().getY() << " " 
    		 << "Type : " << data.getA().getType() << " "
    		 << "Num  : " << data.getA().getNum() << endl;
    }
     
    template <class T>
    void AVLTree<T>::GetNumSeg(T &data, QVector<T> &v, Point &p) {
    	if(data.getNum() == p.m_num_seg_1 ||
    	  (data.getNum() == p.m_num_seg_2))
     
    		v.append(data);
    }
    que je passe en tant que paramètre respectivement aux fonctions suivantes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    void parcours_prefixe(CNode<T> *, void (*f) (T &));
     
    void parcours_prefixe_get(CNode<T> *, QVector<T> &, Point &,
    				   void (*f) (T &, QVector<T> &, Point &));
    Pour le premier template et pointeur de fonction, l'appel suivant est correct:
    où sweep_line et un AVLTree<Segment>, getRacine() retourne un CNoeud<T> *
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    sweep_line.parcours_prefixe(sweep_line.getRacine(), Fonction);
    mais lorsque je fait l'appel de parcours_prefixe_get suivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    sweep_line.parcours_prefixe_get(sweep_line.getRacine(), 
    					    twoseg, event,
    					    GetNumSeg);
    j'obtiens une erreur de undefined alors que twoseg est bien un QVector<Segment>, event un point.

    Est ce que l'erreur vient du fait que j'utilise des paramêtres passé à parcours_prefixe_get dans GetNumSeg ?

    Merci de vos éclaircissements.

  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
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    Je suis même surpris que tu dises que cela marche avec la première fonction. A moins qu'elle ne soit statique, Fonction et GetNumSeg sont des fonctions membres de AVLTree<T> et parcours_prefixe et parcours_prefixe_get aurait plutôt du ressembler à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template<class T>
    void parcours_prefixe(CNode<T> *, void (AVLTree<T>::*f) (T &));
     
    template<class T>
    void parcours_prefixe_get(CNode<T> *, QVector<T> &, Point &,
    				   void (AVLTree<T>::*f) (T &, QVector<T> &, Point &));
    Et être appelée avec une instance de AVLTree<T>.

    Sinon, plutôt qu'un pointeur de fonction pourquoi ne pas aller jusqu'au bout de la paramétrisation de tes 2 fonctions avec un paramètre générique représentant un objet callable qui pourrait ensuite être utilisé soit avec un foncteur, soit avec un std::function, soit un lambda et autres joyeusetés ?

  3. #3
    Membre habitué Avatar de mensoif
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    248
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 248
    Points : 129
    Points
    129
    Par défaut
    Merci de t'intéresser à ma question.

    J'ai donc fait un appel de la sorte:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    sweep_line.parcours_prefixe_get(sweep_line.getRacine(), 
    				    twoseg, event,
    				    sweep_line.GetNumSeg);
    mais ce n'est pas fonctionnel, vous parliez bien de ça ?

    Pour le reste, je bidouille, car c'est pour un projet à rendre demain matin, et les functors ne sont plus très frais dans ma tête.. donc même si c'est moche, je fais au plus rapide :p

    merci

    ps: en ce qui concerne les fonctions, elles ne sont pas déclarées en tant que static.

  4. #4
    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
    Points : 13 017
    Points
    13 017
    Par défaut
    Ce serait plutôt :
    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
     
    template<class T>
    struct dummy
    {
        void une_fonction(T)
        {}
    };
     
    template<class T>
    void fonction(T const &t_, dummy<T> d_, void (dummy<T>::*pf)(T ))
    {
        (d_.*pf)(t_);
    }
     
    int main()
    {
        dummy<int> d;
        fonction(1,d,&dummy<int>::une_fonction);
        return 0;
    }
    ou avec functional :
    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
    #include <functional>
    template<class T>
    struct dummy
    {
        void une_fonction(T )
        {}
    };
     
    template<class T, class functor_t_>
    void fonction(T t_, functor_t_ f)
    {
        f(t_);
    }
     
    int main()
    {
        dummy<int> d;
        fonction(1,std::bind1st(std::mem_fun(&dummy<int>::une_fonction),&d));
        return 0;
    }
    ou à décliner avec std/boost::bind si std::mem_fun et std::bind1st ne conviennent pas.

  5. #5
    Membre habitué Avatar de mensoif
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    248
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 248
    Points : 129
    Points
    129
    Par défaut
    j'ai testé la méthode avec les templates, mais ça ne fonctionnait toujours pas :o
    pour les functors, je n'ai pas le temps de me remettre dedans vus la date de rendus, même si c'est plus élégant.

    Donc bidouillage pour ma part, mais je suis toujours dispo pour essayer de trouver la raison de ça, et au passage, j'ai remis la déclaration de Fonction dans le cpp de ma classe Canevas, et ça fonctionne alors qu'elle n'est même pas déclaré dans le .h , très étrange :o

Discussions similaires

  1. template et pointeur de fonction.
    Par ZaaN dans le forum Langage
    Réponses: 10
    Dernier message: 11/08/2007, 08h15
  2. Déclaration de pointeur de fonction et structure
    Par ShaiLeTroll dans le forum Delphi
    Réponses: 28
    Dernier message: 05/04/2007, 10h48
  3. Pointeur de fonction membre template
    Par bolhrak dans le forum Langage
    Réponses: 6
    Dernier message: 12/12/2006, 14h47
  4. Réponses: 13
    Dernier message: 03/10/2005, 18h06
  5. Réponses: 4
    Dernier message: 08/02/2005, 20h47

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