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][STL] Template de vector et pointeur de fonction


Sujet :

Langage C++

  1. #1
    Nouveau membre du Club Avatar de legend666
    Étudiant
    Inscrit en
    Mars 2004
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 33

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2004
    Messages : 54
    Points : 39
    Points
    39
    Par défaut [Template][STL] Template de vector et pointeur de fonction
    Salut !

    J' essaye de créer en C++ une classe permettant d'utiliser plus facilement les tableaux de pointeurs de fonction. Pour cela, j' ai créer la classe 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
    18
    19
    20
     
    class REDIRECT
    {
    public:
      typedef void(REDIRECT::* pt2member) (void);
     
      void aha(void) {
        cout << "wcsv" << endl;
        return;
      }
     
      void add(string occurence, pt2member function); //add an instruction
      void del(string occurence, pt2member function); //delete an instruction
      template<class T>
      void test(string occurence, T myClass); //test all instruction
     
    private:
      vector < pt2member > listINS; //list of all instruction
      vector < string > listOCC; //list of all occurence
    };
    Aucun problème, ma classe marche sans problème. Mais le seul hic c'est qu' avec cette classe, on ne peut utiliser seulement les mèthodes membres de la dite classe. Pour remedier à cela j' ai essayé de remplacé le type pt2member par des template, mais la classe vector de la STL ne veut pas de template comme type...



    Merci d'avance

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Essaye de regarder du côté de boost::function. Mais dans tous les cas, je ne sais pas si tu pourras stocker des instances de fonctions membres de classes différentes dans un même conteneur.

  3. #3
    Nouveau membre du Club Avatar de legend666
    Étudiant
    Inscrit en
    Mars 2004
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 33

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2004
    Messages : 54
    Points : 39
    Points
    39
    Par défaut
    Est-ce que tu aurais des liens pour la doc de cette librairie ? Ou du moins des exemples par ce que j' ai pas trop compris la doc officiel .

  4. #4
    Nouveau membre du Club Avatar de legend666
    Étudiant
    Inscrit en
    Mars 2004
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 33

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2004
    Messages : 54
    Points : 39
    Points
    39
    Par défaut
    Hum, j' ai reussi à avancé sur le points de vues des templates grace à la page suivante: http://emmanuel-remy.developpez.com/...e/template.htm . La classe est maintenant un template, et je ne sais pour quelle raison, mais la classe vector de la STL n' a rien contre un template "generalisé" de la classe. J' obtiens ainsi le code suivant:

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    template < class Type >
    class REDIRECT
    {
    public:
      typedef void(Type::* pt2member) (void);
      void add(string occ, pt2member function);
     
      template < class T >
      void test(string occ, T myClass);
     
    private:
      vector < pt2member > listINS; //list of all instruction
      vector < string > listOCC; //list of all occurenc
     
    };
     
     
    template < class Type >
    void REDIRECT < Type >::add(string occ, pt2member function)
    {
      listOCC.push_back(occ); //add occurence to list
      listINS.push_back(function); //add function to list
     
      return;
    }
     
    template < class T >
    void test(string occ, T myClass)
    {
      int i;
      for(i = 0; i < listOCC.size(); i++)
      {
        if(listOCC[i] == occ)
          callMemberFunction(myClass, listINS[i]) ();
      }
     
      return;
     
    }
     
    class AFF
    {
      public:
        void go() {
          cout << "Hello !" << endl;
        }
    };
     
     
    int main()
    {
      REDIRECT<AFF> test;
      AFF afficher;
     
      test.add("go", &AFF::go);
      test.test("go", test);
      return 0;
    }
    Mais, comme vous pouvez le voir, j' ai du supprimé un template pour la fonction test, ce qui ammenne bien sur au linkage une erreur car celui ci crois qu' il faut utiliser le template de la classe et nom celui utilisé pour les arguments. Hum je pense que le message d' erreur du linkeur sera plus clair que moi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    "vector.tcc" : /usr/include/c++/3.3/bits/vector.tcc undefined reference to `void REDIRECT<AFF>::test<REDIRECT<AFF> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, REDIRECT<AFF>)' en ligne 236
    Voila,donc ma question est maintenant: est-ce tout d' abord possible, et si oui, comment, de posseder 2 types de templates dans une classe ?



    Merci d' avance

  5. #5
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    template < class Type >
    template < class T >
    void REDIRECT < Type >:: test(string occ, T myClass)
    {
        ...
    }
    :

  6. #6
    Nouveau membre du Club Avatar de legend666
    Étudiant
    Inscrit en
    Mars 2004
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 33

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2004
    Messages : 54
    Points : 39
    Points
    39
    Par défaut
    ARGH !

    Deux bourde de ma part:

    La première, ENORME est l' oubli du "void REDIRECT<T>::" !
    La deuxième est que je pasais comme argument a la fonction test une instanciation de redirect !

    Donc, au final, voici mon code au complet pour ce que ce pourrait aider:

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
     
    #include <iostream>
    #include <vector>
    #include <string>
     
    #define callMemberFunction(object,ptrToMember)  ((object).*(ptrToMember))
     
    using namespace std;
     
     
     
    template < class Type>
    class REDIRECT
    {
    public:
      typedef void(Type::* pt2member) (void);
      void add(string occ, pt2member function);
     
      template <class T>
      void test(string occ, T myClass);
     
    private:
      vector < pt2member > listINS; //list of all instruction
      vector < string > listOCC; //list of all occurenc
     
    };
     
     
     
    template < class Type>
    void REDIRECT < Type >::add(string occ, pt2member function)
    {
      listOCC.push_back(occ); //add occurence to list
      listINS.push_back(function); //add function to list
     
      return;
    }
     
    template < class Type >
    template < class T >
    void REDIRECT < Type >:: test(string occ, T myClass)
    {
      int i;
      for(i = 0; i < listOCC.size(); i++)
      {
        if(listOCC[i] == occ)
          callMemberFunction(myClass, listINS[i]) ();
      }
     
      return;
     
    }
     
    class AFF
    {
      public:
        void go() {
          cout << "Hello !" << endl;
        }
    };
     
     
    int main()
    {
      REDIRECT<AFF> test;
      AFF afficher;
     
      test.add("go", &AFF::go);
      test.test("go", afficher);
      return 0;
    }
    Merci beaucoup !

  7. #7
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Par contre tu devrais utiliser un std::map, étant donné que tes pointeurs de fonctions sont associés à des chaînes. Cela t'évitera de devoir gérer en parallèle deux vecteurs.

    Tu devrais aussi passer ton paramètre de type T par référence, car là tu vas appeler des fonctions membres sur des copies. Je ne pense pas que ce soit ce que tu veux.

    Enfin, pour pinailler, je doute de l'utilité de ta macro d'appel de fonction membre. D'autant plus qu'elle n'apparaitra qu'une fois dans le code, puisque le but de ta classe est justement d'encapsuler les appels de fonctions membres.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    map<string, pt2member> listINS;
     
    template < class Type>
    void REDIRECT < Type >::add(const string& occ, pt2member function)
    {
       listINS[occ] = function;
    }
     
    template < class Type >
    template < class T >
    void REDIRECT < Type >:: test(const string& occ, T& myClass)
    {
        (myClass.*listINC[occ])();
    }
    Après on peut ajouter divers tests, ou encore une surcharge pour les fonctions / instances constantes...

    [edit] Question à 3 sous : pourquoi introduire un type T différent de Type, dans la fonction de test ? C'est pour gérer les objets polymorphiques ?

  8. #8
    Nouveau membre du Club Avatar de legend666
    Étudiant
    Inscrit en
    Mars 2004
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 33

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2004
    Messages : 54
    Points : 39
    Points
    39
    Par défaut
    Ok, merci pour tes conseils , mais je ne comprends ce que tu veux dire par gerer les objets polymorphique: c-à-d pour les constructeur des objets ?! (hum je crois que je suis fatiqué là bonne nuit)

  9. #9
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Je voulais parler de ça :

    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
    struct Base
    {
        virtual void Do();
    };
     
    struct Derivee : Base
    {
        virtual void Do();
    };
     
    int main()
    {
        REDIRECT<Base> test;
        Derivee d;
     
        test.add("Do", &Base::Do);
        test.test("Do", d);
     
        return 0;
    }
    Mais tu n'as pas répondu à la question

  10. #10
    Nouveau membre du Club Avatar de legend666
    Étudiant
    Inscrit en
    Mars 2004
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 33

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2004
    Messages : 54
    Points : 39
    Points
    39
    Par défaut
    Hum heuh non je n' y avais pas pensé !

    Bon tant mieux on va dire...

  11. #11
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Du coup on sait toujours pas pourquoi tu avais fait ça, alors. C'est pas pour t'embêter hein, c'est juste que ça m'intéresse.

  12. #12
    Nouveau membre du Club Avatar de legend666
    Étudiant
    Inscrit en
    Mars 2004
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 33

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2004
    Messages : 54
    Points : 39
    Points
    39
    Par défaut
    Hum, soyons honnête, j' avais fait ca un peu au pif quand j' obtenais l' erreur de template, j' avais essayé cette methode, sans resultat. Et puis j' ai oublié de l' enlever....

  13. #13
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    OK

    N'oublie pas de cliquer sur si c'est bien le cas.

  14. #14
    Nouveau membre du Club Avatar de legend666
    Étudiant
    Inscrit en
    Mars 2004
    Messages
    54
    Détails du profil
    Informations personnelles :
    Âge : 33

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2004
    Messages : 54
    Points : 39
    Points
    39
    Par défaut
    Ok. Donc après les "optimisation":

    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
     
    #include <iostream>
    #include <string>
    #include <map>
     
    using namespace std;
     
    template < class Type>
    class REDIRECT
    {
    public:
      typedef void(Type::* pt2member) (void);
      void add(const string& occ, pt2member function);
      void test(const string& occ, Type& myClass);
     
    private:
      map<string, pt2member> listINS;
     
    };
     
    template < class Type>
    void REDIRECT < Type >::add(const string& occ, pt2member function)
    {
      listINS[occ] = function;
     
      return;
    }
     
    template < class Type >
    void REDIRECT < Type >:: test(const string& occ, Type& myClass)
    {
      if(listINS.find(occ) != listINS.end())
        (myClass.*listINS[occ])();
     
     
      return;
    }
     
    class AFF
    {
      public:
        void go() {
          cout << "Hello !" << endl;
        }
    };
     
     
    int main()
    {
      REDIRECT<AFF> test;
      AFF afficher;
     
      test.add("go45", &AFF::go);
      test.test("go", afficher);
     
      cout << "END !" << endl;
      return 0;
    }
    Merci encore !

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

Discussions similaires

  1. 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
  2. Réponses: 2
    Dernier message: 07/12/2007, 02h19
  3. template et pointeur de fonction.
    Par ZaaN dans le forum Langage
    Réponses: 10
    Dernier message: 11/08/2007, 08h15
  4. Pointeur de fonction membre template
    Par bolhrak dans le forum Langage
    Réponses: 6
    Dernier message: 12/12/2006, 14h47
  5. héritage et template STL
    Par jevito dans le forum Langage
    Réponses: 5
    Dernier message: 21/09/2005, 11h15

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