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

C++ Discussion :

Pb de remove_if


Sujet :

C++

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Par défaut Pb de remove_if
    Bonjour,

    j'aimerais supprimer un élément d'un conteneur list avec à l'aide de la fonction list::remove_if + un foncteur.
    Bon, j'ai l'impression que VC6 ne veut pas. Trop vieux !
    Et je ne peux pas en changer ...

    Donc j'ai vu dans la faq qu'on pouvait utiliser l'idiome erase - remove.

    J'avoue que je ne comprends pas pourquoi il faut utiliser un erase() en plus du remove() ???
    Apparemment d'aprés la faq, "std::remove va déplacer les éléments à supprimer à la fin du conteneur, puis la fonction membre erase() va les supprimer définitivement".
    C'est quand même bizarre non ?

    Comme je stocke des pointeurs, il me faudrait les désallouer aussi. Ou vaut-il miex que je le fasse ? Dans mon foncteur ?

    Voilà ce que j'ai fait :
    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 PredFindByTime
    {
    private : 
    	DWORD limit;
    public:
    	PredFindByTime(DWORD t) : limit(t) {}; 
        bool operator () (const CRequest* pReq) const {
            //return (bool)( pReq->IsPending() == FALSE && (pReq->GetTime() + limit) < GetTickCount() );
    		if ( pReq->IsPending() == FALSE && (pReq->GetTime() + limit) < GetTickCount() )
    		{
    			delete pReq;
    			pReq = NULL;
    			return true;
    		}
    		else
    			return false;
    	}
    };
     
     
    m_listWaitingRequests.erase(std::remove_if( m_listWaitingRequests.begin(), m_listWaitingRequests.end(), PredFindByTime(lmSec) ) );
    @+

  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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Apparemment d'aprés la faq, "std::remove va déplacer les éléments à supprimer à la fin du conteneur, puis la fonction membre erase() va les supprimer définitivement".
    C'est quand même bizarre non ?

    Comme je stocke des pointeurs, il me faudrait les désallouer aussi. Ou vaut-il miex que je le fasse ? Dans mon foncteur ?
    Tu vas tout de suite comprendre l'intérêt de séparer en deux le erase / remove :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    std::list<CRequest*>::iterator Begin = std::remove_if( m_listWaitingRequests.begin(), m_listWaitingRequests.end(), PredFindByTime(lmSec));
     
    for (std::list<CRequest*>::iterator It = Begin ; It != m_listWaitingRequests.end(); ++It)
        delete *It;
     
    m_listWaitingRequests.erase(Begin, m_listWaitingRequests.end());
    A noter que tu avais une erreur dans ton code : tu ne supprimais que l'itérateur renvoyé par std::remove_if, or il faut supprimer tous les élements à partir de cet itérateur jusqu'à la fin du conteneur.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Par défaut
    Ok
    remove_if renvoie un iterateur sur le premier élément à supprimer, et déplace tous les éléments à supprimer à la fin de la liste.
    Donc, grâce à ça, on peut y agir + facilement dessus pour les supprimer puisqu'il suffit d'appeler erase(begin, v.end), et moi j'avais brillamment oublié le v.end
    Merci beaucoup.

    Par contre, concernant la désallocation, pourquoi ne puis-je le faire dans mon prédicat ?

    @+

  4. #4
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Citation Envoyé par olive_le_malin
    Par contre, concernant la désallocation, pourquoi ne puis-je le faire dans mon prédicat ?
    Disons que c'est plus générique ; ça te permettra si besoin de réutiliser ton foncteur pour autre chose où tu ne voudras pas forcément détruire les pointeurs.
    Et puis mieux vaut éviter les effets de bord dans les prédicats, surtout qu'ici le nom que tu lui a donné (PredFindByTime) n'évoque pas du tout le fait qu'il effectue une désallocation.

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Par défaut
    Ouais ... c'est vrai !!
    Merci beaucoup pour tes conseils.

    PS : j'aurais préféré pouvoir utiliser directement un list.remove_if(begin, end, predicat)

  6. #6
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    PS : j'aurais préféré pouvoir utiliser directement un list.remove_if(begin, end, predicat)
    Faut faire certaines concessions avec Visual C++ 6
    C'est dommage que tu ne puisses pas prendre un compilo plus récent, d'autant plus qu'il en existe plein de bons et gratuits de nos jours.

  7. #7
    Membre Expert
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Citation Envoyé par Laurent Gomila
    Faut faire certaines concessions avec Visual C++ 6
    C'est dommage que tu ne puisses pas prendre un compilo plus récent, d'autant plus qu'il en existe plein de bons et gratuits de nos jours.
    Pour ne citer que Code::Blocks

  8. #8
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    577
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 577
    Par défaut
    OK,
    je sais bien ... j'en essaierai bien d'autres,
    mais j'ai plein de codes avec les MFC, alors vous m'avez compris, difficile de prendre autre chose que VC++.

    Perso, j'ai VC2005.
    Mais à ma boîte, c'est toujours VC6

    @+
    et merci

  9. #9
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Citation Envoyé par poukill
    Pour ne citer que Code::Blocks
    C'est pas un compilo.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

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

Discussions similaires

  1. Invalidation itérateurs deque remove_if
    Par thomas41 dans le forum C++
    Réponses: 7
    Dernier message: 04/05/2011, 19h19
  2. questrion sur le remove_if erease et contenaire
    Par yan dans le forum SL & STL
    Réponses: 6
    Dernier message: 10/05/2008, 21h22

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