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. #21
    Invité
    Invité(e)
    Par défaut
    C'est impossible de le faire dans des conditions acceptable, c'est à dire sans recourrir à un classe de base sans fonction et qui necessite un dynamic_cast... En fait tout dépend de l'emplacement où tu veux passer les arguments à la fonction. En fait dans ta fonction time_ptr::analyze_time tu souhaiterai appeler un fonction sans argument. C'est à dire que ton vector est du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::vector< std::function<void()> > funcVector_;
    Le problème se pose au moment de l'ajout de la fonction. La solution est d'utilise un binder, par exemple std::bind (si je me souviens bien boost::bind est à peu près équivalent) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template<class Func, class Arg1>
    void ajouter_fonction( Func func, Arg1 arg1)
    {
          funcVector_.push_back
          (
                 std::bind
                 (
                       func,                     /// la fonction à binder
                       arg1                     /// les arguments déjà connus
                  )
           );
    }
    Vu que bind ne se limite pas à ça je te conseille d'aller jeter un coup sur la doc de boost.bind et par la même occasion celle de boost.lambda. Et si tu as du temps à perdre, regarde la section 20.8 du draft du nouveau standard du C++. Enfin tu peux aller voir du coté de DevX C++, c'est un peu vieux mais il présente pas mal de nouveauté du C++11, par exemple les fonctions lambdas

  2. #22
    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 pour cette nouvelle façon de faire qui compile parfaitement dans mon cas. Cependant, l'exécutable plante au moment où la fonction est sensée être déclenchée, le pointeur this semble être à l'adresse 0x0 donc inexistant (je crois). Qu'est-ce qui ne va pas dans ce code ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    template<class Func, class Instance, class Arg>
            void add_function_ptr2(Func func, Instance instance, Arg arg, float time)
            {
                m_time_vector2.push_back(boost::bind(func,boost::ref(instance),arg,true)); //ajout de la fonction au std::vector
                m_time_wait_ptr2.push_back(time);
                m_current_time_ptr2.push_back(0.f);
            }
    (pour l'initialisation)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    for(int i=0;i<m_time_vector2.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_time_vector2[i](); //lancement de la fonction
                    }
                }
    (pour le lancement de la fonction)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    std::vector< boost::function<void()> > m_time_vector2;
            std::vector<float> m_time_wait_ptr2;
            std::vector<float> m_current_time_ptr2;
    (tableaux déclarés en temps qu'attributs de la classe)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    add_ptr2_time(&MainWindow::SetWidthWindow,this,5,1.f);
    (ajout d'une fonction membre de MainWindow au sein d'une instance de MainWindow (d'où le this) au tableau de fonction)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void MainWindow::SetWidthWindow(int width, bool relative)
    {
        if(relative == true)
        {
            std::cout<<"width : "<<m_window->GetWidth()<<" add "<<width<<std::endl; //plante
            std::cout<<"height : "<<m_window->GetHeight()<<std::endl;
            m_window->SetSize(m_window->GetWidth()+width,m_window->GetHeight());
        }
        else
            m_window->SetSize(width,m_window->GetHeight());
    }
    (endroit du crash, l'erreur ne provient pas de m_window mais d'une fonction semblant inexistante)

    Voilà, si vous avez besoin de plus de précisions, n'hésitez pas à me le faire savoir ! Et pardonnez mon vocabulaire approximatif (les templates et boost j'avais encore jamais fait il y a 15 jours et je manque d'entrainement)

  3. #23
    Invité
    Invité(e)
    Par défaut
    Sans chercher bien loin, lors de l'ajout de la fonction:
    Le type paramétré Instance est du même type que le this appelant : MainWindow*. bind() est assez intelligent pour appeler un fonction membre à l'aide d'un pointeur ou d'une réference vers l'instance de la classe. Sauf qu'ici tu fourni un référence vers un pointeur, nommé instance. Le pointeur, qui suit les règles de la durée de vie des objet, est détruit a la fin de la fonction add_function_ptrx(). La référence que tu a passé à bind(), et qui continue d'exister quelque_part, à l'interieur d'un boost::function, fait toujours référence vers ce pointeur qui lui-même n'existe, c'est un dangling reference. Ensuite quand tu essaye lors de l'appel de bost::function<>::operator(), ton programme tente d'operer un zone de mémoire qui (dans le meilleur des cas) ne lui a pas été alloué et donc (heureusement) crash.

  4. #24
    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
    Ca marche nikel merci !
    Par contre je voulais savoir si il était possible de modifier un argument passé à la fonction boost::bind(func,instance,arg,true) dans n'importe quelle autre fonction sans rajouter template<class Func, class Instance, class Arg> au dessus de la fonction ? (pas très bien exprimé mais je pense que vous m'avez compris)

  5. #25
    Invité
    Invité(e)
    Par défaut
    Là j'ai du mal à te suivre... Pourrais-tu donner un exemple concret de ce que tu veux faire ?

  6. #26
    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
    Oui je te comprends j'explique très mal
    alors je vais essayer de mieux faire.
    Pour l'instant, les fonctions contenues dans le std::vector<boost::function<void()>> sont bien lancées avec les bons paramètres au bon endroit. Cependant, l'initialisation de ces fonctions ne se fait qu'à un seul endroit (dans la fonction MainWindow::add_function_ptr2) et les paramètres qu'elle donne à la fonction "actuelle" ne peuvent être changés. Cela signifie par exemple que je pourrai créer une fonction qui augmentera la taille de la fenetre de 5 pixels de largeur toutes les 100 millisecondes mais que je ne pourrai pas changer cette valeur à 10 ou 20 pixels, il me faudrait pouvoir "rebind" la fonction sans avoir besoin des types génériques Func et Instance et en modifiant juste les paramètres de la fonction. En d'autres termes, j'aimerais avoir une autre fonction capable de modifier directement les paramètres d'une fonction du tableau à l'index i sans template (ou juste 1 pour le paramètre à changer).

    Pour l'instant, j'ai ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    template<class Func, class Instance, class Arg>
            void add_function_ptr2(Func func, Instance instance, Arg arg, bool bool_parameter, float time)
            {
               m_time_vector_ptr2.push_back(boost::bind(func,instance,arg,true));
               m_time_wait_ptr2.push_back(time);
               m_current_time_ptr2.push_back(0.f);
            }
    et je voudrai obtenir en plus :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template<typename T>
    void bind_ptr2(int i, T parameter)
            {
                m_time_vector_ptr2 = boost::bind(????????????,??????????,parameter,true);
            }
    Quel casse-tête

  7. #27
    Membre éprouvé Avatar de oxyde356
    Homme Profil pro
    Ingénieur Recherche Imagerie
    Inscrit en
    Février 2006
    Messages
    797
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur Recherche Imagerie

    Informations forums :
    Inscription : Février 2006
    Messages : 797
    Points : 1 087
    Points
    1 087
    Par défaut
    En somme tu veux pouvoir changer les paramètres de la fonction à son appel ?
    Pour ça il suffit d'utiliser comme argument au bind : _1 ; _2 ...
    Voir : http://www.boost.org/doc/libs/1_46_1...bind/bind.html
    A partir de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    bind can handle functions with more than two arguments, and its argument substitution mechanism is more general:
     
    bind(f, _2, _1)(x, y);                 // f(y, x)
     
    bind(g, _1, 9, _1)(x);                 // g(x, 9, x)
     
    bind(g, _3, _3, _3)(x, y, z);          // g(z, z, z)
     
    bind(g, _1, _1, _1)(x, y, z);          // g(x, x, x)
    ça change des posts moyens à 15 ans : "je veux faire un mmorpg révolutionnaire alors que je n'ai aucune connaissance" ça fait plaisir

  8. #28
    Invité
    Invité(e)
    Par défaut
    Par contre si tu ne connais pas la fonction à binder, le paramètre Func, tu ne va pas pouvoir utiliser bind()...
    Un autre interêt(qui peut parfois poser des problèmes) de bind() est qu'il peut accepter plus d'argument que la fonction qu'il binde. LEs argument suplémentaire seront tous simplement ignorés :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void maFonction(int a);
    void monAutreFonction(int a, bool b);
     
    std::vector<std::function<void(bool)> > vecFonction;
    vecFonction.push_back(std::bind(maFonction, 5) );   // ok
    vecFonction.push_back(std::bind(monAutreFonction, 5, _1) );   // ok
     
    vecFonction[1](true); // appelle monAutreFonction(5, true)
    vecFonction[0](true); // appelle maFonction(5), true est ignoré

  9. #29
    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, donc je pense que je vais passer outre ce petit détail car je dois dire que je ne sais pas où regarder pour trouver comment faire pour modifier un boost::function sans remettre les templates de fonction et d'instance dans mon cas, ou alors je les remettrai mais cela n'aura plus beaucoup d'intéret. Sinon existe-t-il des conteneurs dans boost pouvant contenir une mutlitude de types, par exemple un conteneur qui peut contenir à la fois des int, float, sf::color ... Ca me serait bien utile mais je doute que cela existe mis à part si on place ces types dans une structure mais le problème se pose alors à l'instancialisation et à l'ajout d'instances de cette structure dans un std::vector

    Edit : boost::variant semble convenir, mais boost::bind n'accepte pas ce genre de type en argument, ni boost::any d'ailleurs. J'ai une vague idée de la cause mais c'est encore un peu brouillon dans ma tête

  10. #30
    Invité
    Invité(e)
    Par défaut
    En fait bind accepte any ou variant si et seuleument si la fonction à binder les accepte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void fonctionAny(boost::any const& any);
    void fonctionVariant(boost::variant<int, float, char> const& variant);
    boost::bind(fonctionAny, boost::any("Bonjour"));
    boost::bind(fonctionVariant, boost::variant<int, float, char>(5.3f));

  11. #31
    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 merci je ferai d'une autre façon alors Bon je vais terminer ce que je suis en train de faire avant de mettre ce post en résolu, on ne sait jamais ce qui peut encore arriver

  12. #32
    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 viens de rentrer d'une semaine de vacances, et je dois déjà remonter ce post , même si je ne sais pas si il peut encore faire partie de cette partie du forum (ce n'est plus un problème de template mais de boost). En fait, je voudrais faire quelque chose de plus "élaboré" . Je m'explique : actuellement, et ceci fonctionne parfaitement, j'appelle cette fonction pour ajouter un boost::function à un std::vector :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template<class Func, class Instance, class Arg>
    void add_function_ptr1(Func func, Instance instance, Arg arg)
    {
         m_time_vector_ptr1.push_back(boost::bind(func,instance,arg));
    }
    Le problème , si on peut appeler cela ainsi, est que l'argument passé à la fonction est toujours le même, c'est celui que l'on passe en paramètre. Cependant, j'aimerais que ce paramètre puisse varier avec le temps ou en fonction d'autres objets, par exemple je voudrais qu'une barre que l'on bouge et qui possède une certaine valeur en fonction de l'emplacement du curseur sur la barre agisse directement sur l'argument passé à la boost::function ajoutée, autrement dit j'aimerais que arg puisse être un pointeur de fonction accesseur d'un objet. Est-ce possible ? Si oui, comment dois-je faire (peut-être que c'est simple mais je ne vois pas du tout comment m'y prendre ). Si je me suis mal exprimé ou si vous avez besoin de plus de précision, n'hésitez pas à me le dire

    Merci

  13. #33
    Invité
    Invité(e)
    Par défaut
    J'ai du mal à tout comprendre mais il me semble que ce que tu cherches à utiliser sont les placeholders. Pour reprendre ton exemple de timers :
    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 time_ptr
    {
        std::vector<boost::function<void(time_type)>  > m_time_vector_ptr; // time_type sert à stocker une durée, par exemple un typedef float
    public:
       void add_timer(boost::function<void(time_type)> timer) // c'est l'appelant qui s'occupe de binder la fonction, ça lui laisse plus de liberté
       {
              m_time_vector_ptr.push_back(timer);
       }
     
       void update(time_type interpolation)
       {
             std::for_each
             (
                 m_time_vector_ptr.begin(),
                 m_timer_vector_ptr.end(),
                 _1,
                 interpolation
             );
       }
    };

  14. #34
    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 pour ta réponse , mais à vrai dire je viens de trouver quelque chose qui me convient parfaitement, en utilisant des fonctions "setter" des classes surchargées qui peuvent aussi prendre comme argument une boost::function qui est un accesseur d'un autre objet : un exemple sera plus parlant :

    Ces morceaux de codes illustrent la façon dont la couleur d'arrière-plan change en fonction de l'angle d'un objet:


    Pour changer la couleur de fond, on dispose de 2 méthodes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    class MainWindow
    {
            public:
            ....
            void SetColorR(int new_value, bool relative);
            void SetColorR_(boost::function<int()> function, bool relative)
            {SetColorR(function(),relative);}
    };

    On ajoute un "lien" entre la couleur et l'angle d'un objet, la couleur sera mise à niveau toutes les 0.05s
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    add_ptr2_with_ptr_time(&MainWindow::SetColorR_,this,&Object::get_angle_object,m_objects[0],false,0.05,0);

    Observons de plus près cette fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    template<class Func, class Instance, class Func2, class Instance2, class type>
    void add_ptr2_with_ptr_time(Func func, Instance instance, Func2 func2, Instance2 instance2, bool bool_parameter, float time = 1.f, type t)
    {
             m_time_ptr.add_function_ptr2_with_ptr(func,instance,func2,instance2,bool_parameter,time,t);
    }
    m_time_ptr correspond à l'ensemble des fonctions qui seront appelées à un intervalle donné, ici on ne fait qu'ajouter une autre fonction à l'ensemble, le type t sera expliqué plus loin . Observons maintenant d'encore plus près, dans la classe time_ptr (m_time_ptr en est une instance) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    template<class Func, class Instance, class Func2, class Instance2, class type>
    void add_function_ptr2_with_ptr(Func func, Instance instance, Func2 func2, Instance2 instance2, bool bool_parameter, float time, type)
    {
        boost::function<type()> function = boost::bind(func2,instance2);
                m_time_vector_ptr2_.push_back(boost::bind(func,instance,function,bool_parameter));
         m_time_wait_ptr2_.push_back(time);
         m_current_time_ptr2_.push_back(0.f);
    }
    On crée un boost::function de type type (ce qu'on passe en dernier paramètre lors de l'ajout dans la MainWindow) afin d'éviter tout problème d'incompatibilité. mettre cette fonction de type void ne fonctionnait pas malheureusement, c'est pourquoi j'ai trouvé une issue pas très esthétique mais bon du moment que ça marche . Enfin bref, ensuite on ajoute au tableau des fonctions de type ptr2_ un boost::function ("bindé") correspondant à une méthode setter qui sera appelée au moment voulu grâce au temps passé en argument et à une fonction d'analyse de ce temps utilisée par la boucle principale de la MainWindow.

    Voilà, j'espère que vous m'avez compris, si vous avez des idées d'optimisation de cette bouillie infâme de mots sans aucun sens n'hésitez pas à me le faire savoir, et si vous n'avez pas compris, alors j'irai me coucher et je mettrai ce sujet en résolu car je n'arrive pas à expliquer un truc comme ça Enfin bon bref si vous avez un commentaire à faire, faîtes le !

  15. #35
    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
    En gros tu es en train de recoder boost::signals(2) ?

    PS: je suis quand même étonné à la vitesse à laquelle tu arrives à maîtriser les templates et boost, surtout si tu n'y a jamais touché avant. Beaucoup de programmeurs plus âgés n'arriveront jamais à ce niveau de compétence. Bravo ! Tu as un bel avenir devant toi en C++ si tu continues !
    "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)

  16. #36
    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
    Pourrais-tu me donner des exemples d'utilisation de boost::signal ? En effet, mon plus gros problème est de ne pas trop savoir chercher les infos sur internet, car celles que je trouve sont soit trop compliquées ou trop peu détaillées, soit en anglais et, comme boost est un peu trop compliqué pour moi, je ne comprends pas grand chose lorsque les explications sont en anglais . C'est pour ça que je dois souvent refaire des choses qui existent déjà mais que je ne connais pas assez pour les utiliser, enfin ça me fait un bon exercice mais je dois dire que je suis souvent obligé de tatonner sans parfois trop savoir ce que je fais . boost::signal m'a effectivement l'air de pouvoir "remodeler" mon code en code plus propre même si je ne sais pas (du tout) comment l'utiliser. Pouvez-vous m'aidez ?

  17. #37
    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 viens de mettre en place un système de conditions afin que les fonctions ne se déclenchent que lorsque des conditions sont remplies (angle supérieur à 90° par exemple). Je mets donc en place un système ou les conditions ne peuvent être que des int, float ou bool. Seulement voilà, je me heurte à un problème très bizarre : sachant que m_value est une variable de type boost::variant<int,float,bool> et que m_function est une boost::function de type de retour boost::variant<int,float,bool>, voilà ce qui marche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    bool Condition::check_condition()
    {
        if(m_sign == EQUAL)
            return (m_function()==m_value);
        else if(m_sign == INFERIOR)
            return (m_function()<m_value);
    }
    et voilà ce qui ne marche pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    bool Condition::check_condition()
    {
        if(m_sign == EQUAL)
            return (m_function()==m_value);
        else if(m_sign == INFERIOR)
            return (m_function()<m_value);
        else
            return (m_function()>m_value);
    }
    Bizarre non ? Lorsqu'on utilise le mode debug, l'erreur que j'obtiens avec le code suivant, c'est à dire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    10: error: no match for 'operator>' in 'boost::function0<R>::operator()() const [with R = boost::variant<int, float, bool, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_, boost::detail::variant::void_>]() > ((Condition*)this)->Condition::m_value'
    C:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../include/boost/blank.hpp:84: note: candidates are: bool boost::operator>(const boost::blank&, const boost::blank&)
    est outrepassée et le programme se lance. Supprimer bool des boost::variant ne change strictement rien au problème comme je l'avais pensé auparavant en me disant que l'opérateur < n'était peut-être pas défini pour ce type. Voilà Encore un mystère de l'informatique à résoudre, et si vous pouviez m'éclairer ce serait sympa
    J'ajouterais même encore que si on met >= cela ne marche pas non plus, et que si on change l'emplacement de la ligne "buggée", celle-ci reste buggée

    Edit : en faisant comme ça ça marche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    bool Condition::check_condition()
    {
        if(m_sign == EQUAL)
            return (m_function()==m_value);
        else if(m_sign == INFERIOR)
            return (m_function()<m_value);
        else
            return (m_value<m_function());
    }
    Mais vraiment je suis sur le *ul de voir que le fait seul d'inverser les expressions fonctionne, avez-vous une explication à me proposer ?

  18. #38
    Invité
    Invité(e)
    Par défaut
    Dans la lib standard seul la comparaison "inferieur à" est utilisée (set, map, sort(), ....), donc boost::variant n'a implémenté que l'operateur <. Par contre tu as le namespace std::rel_ops qui te définit à partir des operateur == et < tous les autres operateur de comparaison :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Exemple {};
    bool operator<(Exemple const& a, Exemple const& b) { /* ... */ }
     
    {
         Exemple ex1, ex2;
         ex1 > ex2; // erreur
     
         using namespace std::rel_ops;
         ex1 > ex2; // compile !
    }

  19. #39
    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 pour cette explication car je dois dire que je ne comprenais pas très bien pourquoi le compilo rejetait ce code !

  20. #40
    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 maintenant à un nouveau problème , en fait je veux un vector de différents éléments int, float et bool, plus précisément un vector de classe templatée mais avec un type non défini lors de l'initialisation du tableau, ce qui est impossible avec les templates (on ne peut pas créer de vector<Objet> avec un Objet qui est une classe "templatée"). J'ai donc pensé au boost::variant, la classe Objet (appelons la ainsi) est alors construite de façon à ce que le boost::variant attribut de la classe soit le meme que celui passé en argument au constructeur. Jusque la tout va bien. Seulement voila, il me serait nécessaire d'effectuer des opérations élémentaires sur ce boost::variant, via des méthodes add_value, soustract_value... qui prennent en argument un boost::variant qui sera ajouté, retranché ... à l'attribut. Or le compilateur rejette l'addition ou une quelconque opération excepté le signe = ou < de 2 boost::variant et je dois avouer que je suis un peu perdu . Merci de votre aide

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 3 PremièrePremière 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