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

Boost C++ Discussion :

Predicat is_null ?


Sujet :

Boost C++

  1. #1
    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
    Par défaut Predicat is_null ?
    Bonjour,
    Je cherche, je cherche, mais je n'arrive pas à trouver quelque chose qui ressemblerait à ça (ni dans boost, ni dans la STL) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    template<class T>
    struct is_null
    {
       bool operator()(T const *p_)
       {
          return p_==NULL;
       }
    };
    Ca me paraît tellement trivial que je me dis que ça doit bien exister !
    L'objectif est de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
       boost::make_filter_iterator(
          is_null<ChildT>(),
          boost::make_transform_iterator(XXX,boost::bind(&boost::polymorphic_downcast<ChildT*,BaseT>,_1)
    ...

  2. #2
    Membre chevronné
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Par défaut
    Salut Archi,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    std::equal_to<ChildT const*>(0)
    ?
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  3. #3
    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
    Par défaut
    Salut Florian,
    Merci pour la réponse... mais en fait ça me force à faire ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
       boost::make_filter_iterator(
          boost::bind(&std::not_equal_to<ChildT const*>::operator (),boost::ref(std::not_equal_to<ChildT const*>()),static_cast<ChildT const*>(NULL),_1),


    J'ai trouvé autre chose :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
          boost::make_filter_iterator(
          std::logical_not<T*>(),
    Mais j'ai jamais trop aimé les !ptr.

  4. #4
    Membre chevronné
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Par défaut
    Citation Envoyé par 3DArchi Voir le message
    Salut Florian,
    Merci pour la réponse... mais en fait ça me force à faire ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
       boost::make_filter_iterator(
          boost::bind(&std::not_equal_to<ChildT const*>::operator (),boost::ref(std::not_equal_to<ChildT const*>()),static_cast<ChildT const*>(NULL),_1),
    Oula, ça a l'air bizarre…
    Ceci ne suffit pas ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    boost::make_filter_iterator
    (
        boost::bind
        (
            std::not_equal_to<ChildT const*>(),
            0,
            _1
        ),
        //...
    );
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  5. #5
    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
    Par défaut
    Citation Envoyé par Florian Goo Voir le message
    Oula, ça a l'air bizarre…
    Ceci ne suffit pas ?
    Non, pour 2 raisons :
    1/std::not_equal_to est une fonction binaire : d'où le boost::bind avec l'opérateur ;
    2/ Avec boost::bind, NULL doit être typé : d'où le static_cast<ChildT const*>(NULL).

    [EDIT] : j'ai rien dit, j'avais trop vite lu ta réponse. Comme ça, ça marche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
          boost::bind
        (
            std::not_equal_to<ChildT const*>(),
            static_cast<ChildT const*>(NULL),
            _1
        ),

  6. #6
    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
    Par défaut
    En revanche, je galère pour le boost::typeof :
    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
     
    template<class ChildT>
    boost::filter_iterator<
             std::not_equal_to<ChildT const*>,
             boost::transform_iterator<
                BOOST_TYPEOF(boost::bind(&boost::polymorphic_downcast<ChildT*,wxWindow>,_1))
                ,
                BOOST_TYPEOF(wxWindow().GetChildren().end())
             >
    >
    fwx_make_child_wnd_iterator_begin(wxWindow&parent)
    {
          return boost::make_filter_iterator(
             boost::bind(std::not_equal_to<ChildT const*>(),static_cast<ChildT const*>(NULL),_1),
             boost::make_transform_iterator(parent.GetChildren().begin(),boost::bind(&boost::polymorphic_downcast<ChildT*,wxWindow>,_1)),
             boost::make_transform_iterator(parent.GetChildren().end(),boost::bind(&boost::polymorphic_downcast<ChildT*,wxWindow>,_1))
          );
    }
    Ca me fait invariablement planter Visual Express et GCC. J'ai du mal avec BOOST_TYPEOF.
    J'ai essayé :
    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
     
    template<class ChildT>
    boost::filter_iterator<
             std::not_equal_to<ChildT const*>,
             boost::transform_iterator<
                BOOST_TYPEOF_TPL(boost::bind(&boost::polymorphic_downcast<ChildT*,wxWindow>,_1))
                ,
                BOOST_TYPEOF(wxWindow().GetChildren().end())
             >
    >
    fwx_make_child_wnd_iterator_begin(wxWindow&parent)
    {
          return boost::make_filter_iterator(
             boost::bind(std::not_equal_to<ChildT const*>(),static_cast<ChildT const*>(NULL),_1),
             boost::make_transform_iterator(parent.GetChildren().begin(),boost::bind(&boost::polymorphic_downcast<ChildT*,wxWindow>,_1)),
             boost::make_transform_iterator(parent.GetChildren().end(),boost::bind(&boost::polymorphic_downcast<ChildT*,wxWindow>,_1))
          );
    }
    Quand je fais ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        BOOST_TYPEOF(boost::bind(&boost::polymorphic_downcast<wxButton*,wxWindow>,_1)) dummy =
          boost::bind(&boost::polymorphic_downcast<wxButton*,wxWindow>,_1);
       dummy(this);
    Ca passe...
    [EDIT] Et celui-ci, pas de problème je pense :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    BOOST_TYPEOF(wxWindow().GetChildren().end())

  7. #7
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Ça s'écrit tout simplement !_1 non ?
    Ou _1 == 0

  8. #8
    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
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Ça s'écrit tout simplement !_1 non ?
    Ou _1 == 0
    Effectivement, j'ai pas eu le réflex Boost.Lambda. L'écriture est alors beaucoup plus simple et lisible.
    En revanche, j'ai toujours un problème avec BOOST_TYPEOF

  9. #9
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Quelqu'un pourrait expliciter le _1 ?

  10. #10
    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
    Par défaut
    Bonjour,
    Avec boost::lambda, l'écriture _1==NULL crée un foncteur avec un argument._1 est la place de cet argument.
    Le principe est le même avec boost.bind : boost::bind(ma_fonction,_1) crée un foncteur avec un argument et _1 sera la place de cet argument.
    Je t'invite à consulter les docs de boost.bind et/ou boost.lambda pour une meilleur compréhension qu'une pauv' explication approximative de 4 lignes

  11. #11
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Merci, je voulais justement savoir à quelle branche de boost ça appartenait pour pouvoir me plonger dans la doc

  12. #12
    Membre chevronné
    Avatar de Florian Goo
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    680
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2008
    Messages : 680
    Par défaut
    À noter que boost::bind est dans std::tr1 et par conséquent dans le std:: de C++0x
    Cours : Initiation à CMake
    Projet : Scalpel, bibliothèque d'analyse de code source C++ (développement en cours)
    Ce message a été tapé avec un clavier en disposition bépo.

  13. #13
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Le plantage de GCC pour typeof c'est pas une histoire de name mangling ?
    Il faut pas utiliser typeof directement dans le type de retour, il faut passer par un typedef (enfin une méta-fonction du coup, puisqu'il faut que tu lui passes tes paramètres).

  14. #14
    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
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Le plantage de GCC pour typeof c'est pas une histoire de name mangling ?
    Il faut pas utiliser typeof directement dans le type de retour, il faut passer par un typedef (enfin une méta-fonction du coup, puisqu'il faut que tu lui passes tes paramètres).
    Salut,
    Je n'ai pas creusé plus que ça. Car en m'orientant vers Lambda, tu m'as permis de reformuler mon besoin autrement et j'ai pu me passer d'itérateur alambiqué.
    Cependant, en parcourant sommairement la doc Boost.Typeof, je soupçonne qu'il faut faire des BOOST_TYPEOF_REGISTER_TYPE auparavant.

  15. #15
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Ce n'est nécessaire que si ton compilateur ne supporte pas typeof nativement.
    Or GCC le supporte, et MSVC aussi à travers un hack.

    Normalement quand GCC plante, il dit clairement pourquoi. La raison pour laquelle ça ne marche pas est que l'ABI ne permet pas d'avoir typeof (ou même decltype) dans le type de retour.

  16. #16
    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
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Normalement quand GCC plante, il dit clairement pourquoi.
    Précisemment, l'erreur est :
    Citation Envoyé par gcc
    internal compiler error: in write_type, at cp/mangle.c:1579
    Citation Envoyé par loufoque Voir le message
    La raison pour laquelle ça ne marche pas est que l'ABI ne permet pas d'avoir typeof (ou même decltype) dans le type de retour.
    J'avoue que j'aimerais bien que tu développes un peu. En brut, je vois pas trop la problématique...

  17. #17
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Les versions plus récentes de GCC donnent un message plus clair.
    Enfin là c'est suffisamment clair, mangle.c s'occupe bien entendu du name mangling, là où se situe le problème.

    J'avoue que j'aimerais bien que tu développes un peu. En brut, je vois pas trop la problématique...
    L'ABI que GCC utilise ne le permet tout simplement pas. Il va falloir la modifier et en spécifier une nouvelle.

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

Discussions similaires

  1. Un prédicat appelant un autre prédicat
    Par golgot73 dans le forum Prolog
    Réponses: 2
    Dernier message: 09/11/2006, 13h58
  2. convertir une fonction en predicat
    Par seb9999 dans le forum C++
    Réponses: 2
    Dernier message: 19/10/2006, 20h06
  3. Réponses: 17
    Dernier message: 28/09/2006, 16h08
  4. Réponses: 9
    Dernier message: 30/05/2006, 14h57
  5. Comment s'assurer qu'un prédicat retourne NO
    Par C_C dans le forum Prolog
    Réponses: 9
    Dernier message: 10/11/2005, 18h38

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