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

SL & STL C++ Discussion :

STL et prédicat


Sujet :

SL & STL C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Décembre 2007
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 30
    Par défaut STL et prédicat
    Bonjour,
    j'utilise le containeur list de la STL contenant plusieurs éléments de la classe suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class position
    {
    public:
    	int l, m , n;
    	double x;
    	double y;
    	double z;
    }
    Je souhaite supprimer certains éléments de la liste que j'ai créé suivant un critère par exemple n = variable . J'essaie d'utiliser l'algorithme remove_if mais il demande un predicate. Pouvez vous m'aider à comprendre comment marche les prédicats ?
    je regardais sur beaucoup de site et je n'arrive toujours pas a supprimer un élément.
    Je vous remercie d'avance pour votre aide.

  2. #2
    Membre averti
    Inscrit en
    Décembre 2007
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 30
    Par défaut
    Certains parlent d'utiliser bind2nd() ou bind1st(). Quel est la différence ? Comment les utilise-t-on ?
    Si quelqu'un avez plus de renseignement ca serait sympa.

  3. #3
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour,

    On peut voir un prédicat une fonction booléenne qui prend le type stocké dans la liste comme paramètre.

    Il faut donc que tu donnes à remove_if une fonction comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    bool mon_predicat(const position & pos) {
        /* on supprime si n est égal à zero. */
        return (pos.n == 0);
    }
    http://www.cplusplus.com/reference/stl/list/remove_if/

    Pour les bind, voir ce tuto http://r0d.developpez.com/articles/algos-stl/#LI-D

  4. #4
    Membre averti
    Inscrit en
    Décembre 2007
    Messages
    30
    Détails du profil
    Informations forums :
    Inscription : Décembre 2007
    Messages : 30
    Par défaut
    En fait, je cherche plutôt une fonction comme ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    bool mon_predicat(const position & pos, int ma_variable) {
        /* on supprime si n est égal à zero. */
        return (pos.n == ma_variable);
    }
    J'ai cru comprendre qu'un prédicat est une fonction unaire:
    predicate
    Unary predicate that, taking a value of the same type as those contained in the list object, returns true for those values to be removed from the container, and false for those remaining.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     endp = remove_if(list1.begin(), list1.end(),bind2nd(greater<int>(), variable));
    En fait, l'utilisation bind2nd ou bind1st permet d'ajouter un paramètre supplémentaire ce qui serait assez pratique.

  5. #5
    Invité(e)
    Invité(e)
    Par défaut
    En fait, je cherche plutôt une fonction comme ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    bool mon_predicat(const position & pos, int ma_variable) {
        /* on supprime si n est égal à zero. */
        return (pos.n == ma_variable);
    }
    Alors, dans ce cas, il ne faut pas passer par un prédicat fonction, mais par une classe :
    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 predicat{
        predicat(int var) {
            ma_variable = var;
        }
        int ma_variable;
        bool operator () (const position & pos) {
            return (pos.n == ma_variable);
        }
    };
     
    int main() 
    {
        predicat mon_predicat(5);
     
        list<position> ma_liste;
     
        ma_liste.remove_if(mon_predicat);
     
        return 0;
    }
    Si on tiens absolument à utiliser bind1st ou bind2nd, il faut implémenter une binary_function, mais je pense que le comportement final est à peut près équivalent.

  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
    Salut,
    std::ptr_fun permet de créer un foncteur avec une fonction libre.
    std::bind2nd permet de lier le second paramètre du foncteur.
    Ce qui donnerait :
    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
    #include <list>
    #include <algorithm>
    #include <functional>
     
    class position
    {
    public:
    	int l, m , n;
    	double x;
    	double y;
    	double z;
    };
     
    bool mon_predicat(position  pos, int ma_variable) {
        /* on supprime si n est égal à zero. */
        return (pos.n == ma_variable);
    }
     
    int main()
    {
       std::list<position> lst_pos;
       std::remove_if(
          lst_pos.begin(),
          lst_pos.end(),
          std::bind2nd(std::ptr_fun(&mon_predicat),42)
       );
       return 0;
    }
    Malheureusement, ça capture mal la référence constante du premier paramètre, donc un passage par valeur est nécessaire.
    Sinon, avec boost, ça se passe mieux :
    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
    #include <list>
    #include <algorithm>
    #include "boost\bind.hpp"
     
    class position
    {
    public:
    	int l, m , n;
    	double x;
    	double y;
    	double z;
    };
     
    bool mon_predicat(position const& pos, int ma_variable) {
        /* on supprime si n est égal à zero. */
        return (pos.n == ma_variable);
    }
     
    int main()
    {
       std::list<position> lst_pos;
       std::remove_if(
          lst_pos.begin(),
          lst_pos.end(),
          boost::bind(mon_predicat,_1,42)
       );
       return 0;
    }
    Sinon, il reste effectivement la possibilité proposée par Mabu de passer par une structure dédiée :
    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
    #include <list>
    #include <algorithm>
     
    class position
    {
    public:
    	int l, m , n;
    	double x;
    	double y;
    	double z;
    };
    struct mon_predicat
    {
       int ma_variable;
       mon_predicat(int var_):ma_variable(var_){}
       bool operator()(position const& pos) {
           /* on supprime si n est égal à zero. */
           return (pos.n == ma_variable);
       }
    };
     
    int main()
    {
       std::list<position> lst_pos;
       std::remove_if(
          lst_pos.begin(),
          lst_pos.end(),
          mon_predicat(42)
       );
       return 0;
    }
    P.S. C++0x devrais même te faciliter la vie avec les lambdas (non testé mais ça devrait y ressembler peu ou prou) :
    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
    #include <list>
    #include <algorithm>
     
    class position
    {
    public:
    	int l, m , n;
    	double x;
    	double y;
    	double z;
    };
     
    int main()
    {
       std::list<position> lst_pos;
       std::remove_if(
          lst_pos.begin(),
          lst_pos.end(),
          [](position const& pos){return (pos.n == 42);}
       );
     
       return 0;
    }

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

Discussions similaires

  1. problème de références _ptr dans une map STL
    Par Mr_Tyu dans le forum CORBA
    Réponses: 1
    Dernier message: 10/08/2004, 10h39
  2. STL::vector crash a l"execution
    Par sebA dans le forum MFC
    Réponses: 2
    Dernier message: 16/06/2004, 16h36
  3. Probleme de Compilation de la STL
    Par stoluup dans le forum MFC
    Réponses: 3
    Dernier message: 05/05/2004, 17h25
  4. STL : std::set problème avec insert ...
    Par Big K. dans le forum MFC
    Réponses: 13
    Dernier message: 08/11/2003, 01h02
  5. [Kylix] [BCB] pb avec la STL
    Par pykoon dans le forum EDI
    Réponses: 1
    Dernier message: 29/12/2002, 12h56

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