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 :

Problème de template associés à des pointeurs de fonction


Sujet :

Langage C++

  1. #1
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Points : 176
    Points
    176
    Par défaut
    Bonjour à tous ,

    je suis nouveau sur ce forum, j'ai 15 ans et j'ai un problème concernant les templates et les pointeurs de fonction. Je dois avouer que je maîtrise (très) mal les templates mais les quelques recherches que j'ai effectuées ne m'ont pas permis de résoudre mon problème (ou d'une manière beaucoup trop complexe). Je compile sous windows 64bits avec code blocks et mingw meme si cela n'a pas beaucoup d'importance.

    Je développe actuellement un "éditeur" de boutons (correspondant à la classe Object et ses dérivés) en C++ avec la SFML qui devraient pouvoir être interconnectés avec toutes les variables du programme (ou une grande partie) sous forme de pointeurs de fonction : par exemple, une barre peut être connectée à la composante r de la couleur d'un autre objet, un bouton peur être connecté à l'affichage ou non d'un autre objet, un peu à la manière de Qt...

    Je dispose d'une classe centrale qui gère les évènements et le temps en les "redirigeant" vers tous les éléments (ou objets) sous forme de pointeurs de fonction. Le problème est que toutes les fonctions "setter" de toutes les classes présentent de nombreuses différences de patron : il y en a 7 pour l'instant. Le problème est que :

    -toutes les fonctions ne peuvent pas être "activées" (seules celles dont le patron est l'un des 7 patrons définis dans les pointeurs de fonction peuvent l'être)

    -le nombre de fonction pour changer les arguments passés aux fonctions lors de leur activation est multiplié par le nombre de patrons (7).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
            typedef void (MainWindow::*MainWindow_ptrColor)(sf::Color); //pointeur de fonction de MainWindow parametrant une couleur (donc SetColor)
            typedef void (MainWindow::*MainWindow_ptrInt)(int, bool); //pointeur de fonction de MainWindow parametrant une variable entiere
     
            typedef void (Object::*object_ptrFloat)(float, bool); //pointeur de fonction d'objet parametrant une variable flottante
            typedef void (Object::*object_ptrInt)(int, bool); //pointeur de fonction d'objet parametrant une variable entière
            typedef void (Object::*object_ptrString)(std::string); //pointeur de fonction d'objet parametrant un std::string
            typedef void (Object::*object_ptrVoid)(void); //pointeur de fonction d'objet déclenchant une fonction sans paramètre (comme par exemple Move)
            typedef void (Object::*object_ptrColor)(sf::Color); //pointeur de fonction d'objet parametrant une couleur
    Cependant, ce n'est pas du tout pratique car il faut que, pour chaque type de pointeurs, je crée les fonctions utiles pour travailler avec, ce qui multiplie par 7 (le nombre de pointeurs de fonction différents) le nombre de ces fonctions. Dans l'idéal, je voudrais obtenir quelque chose comme ce code qui ne marche pas pour remplacer les 7 pointeurs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
            template <typename T>
            typedef void (MainWindow::*MainWindow_ptrColor)(T,bool);
            template <typename T>
            typedef void (MainWindow::*MainWindow_ptrColor)(T);
            template <typename T>
            typedef void (Object::*MainWindow_ptrColor)(T,bool);
            template <typename T>
            typedef void (Object::*MainWindow_ptrColor)(T);
    erreur du compilo mingw sous code blocks :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    D:\mes documents\SFML\AllButtonsTest - Copie\mainwindow.hpp:19: error: template declaration of `typedef'
    D:\mes documents\SFML\AllButtonsTest - Copie\mainwindow.hpp:21: error: template declaration of `typedef'
    (il y a aussi d'autres erreurs mais qui sont liées à celles ci)

    Ou, encore mieux :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
            template <typename T,typename S>
            typedef void (S)(T,bool);
            template <typename T>
            typedef void (S)(T);
    Je ne sais pas du tout comment faire ! Si vous n'avez pas très bien compris, je peux vous réexpliquer (ce qui m'est difficile )

    Merci d'avance pour votre aide !

  2. #2
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Le problème est bien posé mais malheureusement pour toi, loin d'être trivial en l'état actuel.

    Avant de répondre directement, as tu regardé boost::function ou std::function (si ton compilo gère C++2011) pour voir s'il y avait moyen de retirer tout ce frattra de template. Tu peux même regarder boost::signal2 qui pourrait répondre à tes besoins (émettre des signaux entre des objets).

    Sinon, en l'état actuel de ton problème , je partirais dans la méta programmation [référence à ce sujet] ce qui risque de beaucoup augmenter la complexité de ton code.

    J'ai pas le temps d'essayer d'écrire un proof of concept mais à coup de typelist et macro ca doit se faire. En début de piste est l'utilisation de cette macro:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #define foo(C,type) typedef void (C::*C##type)(type t); \
                                  typedef void (C::*C##type##b)(type t,bool);
    Après, en faisant varier C et type dans des typelist, y'a moyen de générer tout ca automatiquement.

    PS/ 15 ans, tu débutes en C++ et tu veux déjà toucher aux templates ? Tu me rappelles moi il y'a .... 5 ans de cela
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  3. #3
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Points : 176
    Points
    176
    Par défaut
    Tout d'abord merci de m'avoir répondu

    Je ne me suis encore jamais intéressé à la librairie boost et je ne sais pas si je vais l'utiliser car comme tu le dis cela risque d'augmenter la complexité du code et j'ai peur de ne pas comprendre ce que j'écrirai Je pense donc rester sur ce que j'ai fait même si cela demeure trop peu "modulable" mais je vais cependant m'intéresser de plus près à la métaprogrammation et je vais essayer d'utiliser la librairie boost
    Je vous tiens au courant

    Edit : Au fait pourrais tu m'expliquer un peu plus en détail la belle macro que tu me donnes en exemple, j'avoue avoir du mal a la comprendre

  4. #4
    Membre chevronné
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Points : 1 921
    Points
    1 921
    Par défaut
    Citation Envoyé par Lintel-oo Voir le message
    Je ne me suis encore jamais intéressé à la librairie boost et je ne sais pas si je vais l'utiliser car comme tu le dis cela risque d'augmenter la complexité du code et j'ai peur de ne pas comprendre ce que j'écrirai
    La meilleure des compétences a avoir est celle qui consiste a savoir ne pas reinventer la roue. Boost, c'est comme std, ca s'apprend, ca se maitrise et ca s'exploite. Y a rien de "trop compliqué", sinon fallait faire du mecano

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 074
    Points : 12 120
    Points
    12 120
    Par défaut
    Je suis impressionné, à 15 ans, utiliser des templates, c'est déconcertant.

    Très peu de développeur débutant (après un bac+5 ) savent correctement s'en servir.

    Mais, notre orgueil de vieux programmeur est sauf.
    Putai*, Je terminais mes études qu'il ne savait pas encore marcher.

    Bon, la réponse est on ne peut plus simple :

    MSDN:

    Compiler Error C2823

    Send Feedback
    Error Message
    a typedef template is illegal


    Templates are not allowed in typedef definitions.

    The following sample generates C2823:

    // C2823.cpp
    template<class T>
    typedef struct x {
    T i; // C2823 can't use T, specify data type and delete template
    int i; // OK
    } x1;
    Oui, oui pas de template pour les typedef, mais c'est logique.

    Votre mode d'utilisation de ce template ne me semble pas clair.
    Si c'est pour économiser des copier-coller, les MACRO sont bien plus simples.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define TUTU(x) typedef void (__thiscall (##x)::*fn_float_##x )(float a, bool);typedef void (__thiscall (##x)::*fn_int_##x )(int a, bool)

  6. #6
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Si ton compilateur les supporte il y a les alias template (ou template typedef) du C++2011 qui pourrait peut-etre (*) résoudre ton problème. Regardes ici : http://www2.research.att.com/~bs/C%2...template-alias

    (*) Je n'ai jamais testé (marche pas sur mon compilateur) donc je ne peux pas garantir que dans ton cas ca marche. Je pense que la syntaxe serait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    template<class T>
    using ptr_func = void (*)(T);
    Mais je n'en suis pas certain.

  7. #7
    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,
    Sinon, tu peux passer par une structure pour définir les types :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    template <typename T>
    struct mes_traits
    {
            typedef void (MainWindow::*MainWindow_ptrColor)(T);
            template <typename T>
            typedef void (MainWindow::*MainWindow_ptrInt)(T, bool);
    };
    Séances lecture :
    Présentation des classes de Traits et de Politiques en C++ par Alp Mestan
    La métaprogrammation en C++ par Laurent Gomila
    Template rebinding en C++ par Alp Mestan

  8. #8
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Double post avec celui ci Il faudrait les fusionner.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  9. #9
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Points : 176
    Points
    176
    Par défaut
    Merci à tous , je vais regarder tout cela !

    double post avec celui ci Il faudrait les fusionner
    Comment fusionner les post ?

    Edit : ah non je crois que ça a été fait automatiquement

  10. #10
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Points : 176
    Points
    176
    Par défaut
    J'ai résolu une partie du problème , en mettant les pointeurs de fonction template dans une classe. J'y ai ajouté également une fonction qui permet d'ajouter des éléments à un std::vector :

    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 <typename T, typename S>
    class function_pointer_table_time
    {
        public:
            typedef void (S::*ptr)(T);
            typedef void (S::*ptr2)(T, bool);
     
            template <typename U, typename V>
            void add_element_ptr(U type, V parameter)
            {
                m_ptr.push_back(type,parameter);
            }
     
        private:
            std::vector<ptr> m_ptr;
            std::vector<T> m_parameter;
            std::vector<float> m_time;
            std::vector<float> m_current_time;
    };
    Cependant, comme vous pouvez le constater, la classe possède un template générique , donc tout ce qui est contenu dans le vector est finalement du meme type. Je sais que je n'arriverai pas facilement à obtenir quelque chose comme ça (je sais pourquoi ça plante mais je voudrai obtenir un résultat équivalent) :

    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
     
     
    class function_pointer_table_time
    {
        public:
            template <typename T, typename S>
            typedef void (S::*ptr)(T);
            template <typename T, typename S>
            typedef void (S::*ptr2)(T, bool);
     
            template <typename U, typename V>
            void add_element_ptr(U type, V parameter)
            {
                m_ptr.push_back(type,parameter);
            }
     
        private:
            std::vector<ptr> m_ptr;
            std::vector<T> m_parameter;
            std::vector<float> m_time;
            std::vector<float> m_current_time;
    };
    dans lequel je pourrai ajouter n'importe quel type de pointeur. Où dois-je chercher pour avoir quelque chose qui ressemble à ceci ? Dans les classes de traits ? de politiques ? Ou bien est-ce impossible ? En tout cas j'aurai appris déjà beaucoup de chose sur les templates grâce à vous

    Edit : après de nouvelles recherches, il semblerait que ce soit le genre de cas idéal pour le template rebinding. Je vous tiens au courant

  11. #11
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Il faut creuser un peu, mais l'idée de regrouper dans un même conteneur des entités de types différents, ca ressemble à un cas d'application due type-erasure. Alp Mestan a écirt un article sur le sujet, ca pourra t'aider à voir ce que c'est. Il faudra que tu adaptes ensuite.

  12. #12
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Tu ne veux toujours pas regarder boost::function ou boost::signal(2) ?
    Car ca pourrait simplifier grandement ton code.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  13. #13
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Points : 176
    Points
    176
    Par défaut
    grâce eu template rebinding et juste en encapsulant la classe dans une structure sans typedef, déclarer une variable de type cette structure ne pose plus de problèmes ! Reste encore à développer toutes les fonctions qui vont me permettre d'agir sur les pointeurs de fonction !

    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
     
    struct time_ptr
    {
        template <typename T, typename S>
        class function_pointer_table_time
        {
            public:
                typedef void (S::*ptr)(T);
                typedef void (S::*ptr2)(T, bool);
     
                template <typename U, typename V>
                void add_element_ptr(U type, V parameter)
                {
                    m_ptr.push_back(type,parameter);
                }
     
            private:
                std::vector<ptr> m_ptr;
                std::vector<T> m_parameter;
        };
        std::vector<float> m_time;
        std::vector<float> m_current_time;
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    time_ptr m_ptr_i_m;//ne bug pas =)

    PS : Non je n'ai pas le courage de m'attaquer à boost, car je suis un peu "borné" et j'ai du mal à utiliser d'autres bibliothèques (il faut du temps pour apprendre à les utiliser et même si j'en ai beaucoup, je tarde toujours à changer )

  14. #14
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Points : 176
    Points
    176
    Par défaut
    Je me heurte à un nouveau problème
    En effet, je n'arrive pas à lancer la fonction pointée par le pointeur de fonction contenu dans la structure. Je n'arrive pas à vous expliquer mieux que mon code qui n'est pas commenté

    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
    72
    73
    74
    75
    76
     
    struct ptr1__
    {
        template <typename T, typename S>
        struct ptr1_
        {
            typedef void (S::*ptr1)(T);
            T parameter;
        };
    };
     
    struct ptr2__
    {
        template <typename T, typename S>
        struct ptr2_
        {
            typedef void (S::*ptr2)(T, bool);
            T parameter;
        };
    };
     
    class time_ptr // la classe qui contient tous les pointeurs de fonction associés à un certain temps : les fonctions sont exécutées lorsque ce temps est supérieur à un certain seuil
    {
        public:
     
            template <typename T, typename S>
            void add_element_ptr1(T type, S parameter, float time) //pour ajouter un pointeur de fonction de type 1 avec parametre
            {
                ptr1__::ptr1_<T,S> substitut;
                substitut.parameter = parameter;
                m_ptr1.push_back(substitut); //ça marche mais il faudrait trouver autre chose pour remplacer le substitut
                m_time_wait_ptr1.push_back(time);
                m_current_time_ptr1.push_back(0.f);
            }
     
            template <typename T, typename S>
            void add_element_ptr2(T type, S parameter, float time)//pour ajouter un pointeur de fonction de type 2 avec parametre
            {
                ptr2__::ptr2_<T,S> substitut;
                substitut.parameter = parameter;
                m_ptr2.push_back(substitut); //ça marche mais il faudrait trouver autre chose pour remplacer le substitut
                m_time_wait_ptr2.push_back(time);
                m_current_time_ptr2.push_back(0.f);
            }
     
            void analyse_time(float time)
            {
                for(int i=0;i<m_ptr1.size();i++)
                {
                    m_current_time_ptr1[i]+=time;
                    if(m_current_time_ptr1[i]>=m_time_wait_ptr1[i])
                    {
                        m_current_time_ptr1[i]-=m_time_wait_ptr1[i];
                        (*m_ptr1[i].ptr1_<????????????????????>.ptr1)(m_ptr1[i].ptr1_.parameter); //que mettre ici ? comment lancer la fonction avec le pointeur sans utiliser de template ?
                    }
                }
                for(int i=0;i<m_ptr2.size();i++)
                {
                    m_current_time_ptr2[i]+=time;
                    if(m_current_time_ptr2[i]>=m_time_wait_ptr2[i])
                    {
                        m_current_time_ptr2[i]-=m_time_wait_ptr2[i];
                        (*m_ptr1[i].ptr2_<????????????????????>.ptr2)(m_ptr2[i].ptr2_.parameter, true);  //que mettre ici ? comment lancer la fonction avec le pointeur sans utiliser de template ?
                    }
                }
            }
     
        private:
            std::vector<ptr1__> m_ptr1;
            std::vector<float> m_time_wait_ptr1;
            std::vector<float> m_current_time_ptr1;
     
            std::vector<ptr2__> m_ptr2;
            std::vector<float> m_time_wait_ptr2;
            std::vector<float> m_current_time_ptr2;
    };
    En d'autres termes, je ne vois pas comment faire pour modifier les instances de la structure template sans repasser par ceux-ci ! Donc je me retrouve encore une fois bloqué
    Merci de votre aide précieuse

  15. #15
    Invité
    Invité(e)
    Par défaut
    J'ai un peu de mal à suivre...

    Déjà tu affecte un ptr1__::ptr1_<T, S> à un ptr1__(lors du push_back)... Or ces deux type n'ont aucune relation excepté que le nom de ptr1__::ptr1_<T, S> dépend de ptr1__ puisque c'est une classe nested... Ton compilateur accepte cette conversion ? Par prudence il vaut mieux avoir instancié la classe et appelé au moins un fois la fonction add_element_ptr1, sinon le compilateur peut estimer que ptr1__::ptr1_<T, S> dépend des paramètres templates, et que les operations s'appliquant dessus ne peuvent pas être pré-vérifiée.

    Deuxièmement ptr1__::ptr1_<T, S> n'a pas de champs pour stocker une fonction, il n'y a qu'un typedef sans déclaration de variable

    Ensuite tu veux avoir une pointeur de fonction membre, ce qui implique donc la présence ( d'au moins) une instance de classe qui manque... Enfin, elle est présente dans add_element_ptr1 mais elle n'est pas conservée

    D'autre part pourquoi ne pas utiliser un binder et un classe du genre std::fonction ? (présents comme indiqués précédemment dans boost, mais aussi dans Loki, dans le tr1, dans le C++11...)Plus de problème de fonction membre/pas membre, ni de stockage des arguments, tu peux même uniformiser ptr1 et ptr2 !
    Si tu persiste à vouloir réinventer la roue carré, il faut passer par le type erasure pour recreer un classe semblable à std::fonction. Du genre :
    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
     
     
    template<class Ret, class Arg1>
    class FonctionImpl1
    {
    public:
         virtual Ret exec(Arg1 arg1) = 0;
    };
     
    template<class Func, class Ret, class Arg1>
    class FunctorFonctionImpl1 : public FonctionImpl1
    {
        Func fun;
    public:
         virtual Ret exec(Arg1 arg1)
         {
              return fun(arg);
         }
    };
     
    template<class Ret, class Arg1>class Fonction1
    {
        FonctionImpl1* impl_;
    public:
       template<class Func>
       Fonction1(Func fun)
       :impl_(new FunctorFonctionImpl1<Func, Ret, Arg>(fun))
       {}
     
       Ret operator()(Arg1 arg)
       {
            return impl_->exec(arg);
       }
    };
    Et ainsi de suite pour les fonctions à 2, 3, 4, 5, 6... éléments. Sans compter la manière de passer les arguments(par valeur ou par référence ? (*) ), les opérateurs de comparaisons....

    (*) : un élément de réponse se trouve dans les sources à télécharger de dvp.com

  16. #16
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Points : 176
    Points
    176
    Par défaut
    Effectivement je pense que je vais utiliser boost et apprendre à l'utiliser car recréer toutes ces fonctions (réinventer la roue ) est trop difficile . Merci pour ta réponse je m'y mets de ce pas et je vous dit si je trouve encore d'autres problèmes

  17. #17
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut
    Tu n'as probablement pas besoin de boost. Si ton compilateur est assez récent (Vs2008/VS2010 ou gcc 4.x + flag -std=c++0x) alors std::function est directement présent dans la bibliothèque standard, dans le header <functional>.

  18. #18
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Points : 176
    Points
    176
    Par défaut
    Ok je pense que je vais télécharger la dernière version de gcc mingw alors. Cependant, j'ai aussi téléchargé boost , son installation ne me posera pas trop de problème je pense mais pouvez-vous me dire où chercher ? car je me sens un peu perdu au milieu de cette documentation assez énorme et je ne comprends pas tout (je n'ai pour l'instant qu'un faible niveau en anglais ). Auriez-vous des tutoriels à me conseiller ? (de préférence en français) ou pouvez-vous me donner des exemples d'utilisation de std::function ? Je vous remercie

  19. #19
    Invité
    Invité(e)
    Par défaut
    Il faut regarder du coté de Getting Started, scroller jusqu'en bas, Getting Started on Microsoft Windows. La compilation peut être légèrement complexe (vivement cmake !) notamment parce qu'il faut compiler soit même les outils de compilations de boost...

    Pour std::function, qui ressemble en fait fortement à boost::function :
    http://www.boost.org/doc/libs/1_46_1.../tutorial.html Pas besoin de savoir lire l'anglais(même si ça aide), tu essaye de comprendre les bouts de codes puis (éventuellement) tu regarde les notes environnantes !
    Dernière modification par Invité ; 19/04/2011 à 22h40.

  20. #20
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Points : 176
    Points
    176
    Par défaut
    J'aurais une énième question :
    Est-t-il possible de créer un std::vector de boost::function différentes, en d'autres termes est-t-il possible de créer un std::vector qui puisse contenir à la fois des MainWindow::SetColor(sf::Color), des MainWindow::SetWidth(int width), des Object::SetAngle(float angle) et bien d'autres ? Ou bien y a-t-il des solutions qui permettent de s'en approcher ? Sur ce je vais me coucher, dans l'espoir d'arriver un jour à obtenir un code où toutes les fonctions pourraient s'appeler entre elles

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 3 123 DernièreDernière

Discussions similaires

  1. [JOGL] - equivalent des pointeurs sur fonction
    Par sir_gcc dans le forum OpenGL
    Réponses: 2
    Dernier message: 12/01/2009, 20h26
  2. Réponses: 1
    Dernier message: 07/11/2007, 10h06
  3. problème char-actéristique avec des pointeurs
    Par Antigonos Ier Gonatas dans le forum C
    Réponses: 11
    Dernier message: 16/04/2007, 21h22
  4. Transtypages sur des pointeurs de fonction
    Par gege2061 dans le forum GTK+ avec C & C++
    Réponses: 5
    Dernier message: 05/01/2007, 15h01
  5. [Language]Equivalent Java des pointeurs de fonctions du C/C++
    Par Thierry Chappuis dans le forum Langage
    Réponses: 1
    Dernier message: 25/11/2005, 15h14

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