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 :

std::list et erase


Sujet :

C++

  1. #1
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut std::list et erase
    Bonjour, j'ai choisi d'utiliser std::list parce que je pensais que erase n'invalidait pas les iterators. Malheureusement, semblerait que sa ne marche que pour les iterators non supprimés.

    Je vous demande donc conseil sur comment faire quelque chose comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    std::list<...>::iterator it;
    for(it=l.begin();it!=l.end();it++)
    {
          CallFunction(it,l,...);
    }
    Avec CallFunction pouvant faire un l.erase(it);

    Merci de votre aide.

  2. #2
    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
    Citation Envoyé par NoIdea Voir le message
    Bonjour, j'ai choisi d'utiliser std::list parce que je pensais que erase n'invalidait pas les iterators. Malheureusement, semblerait que sa ne marche que pour les iterators non supprimés.
    Mind. Blown.
    J'ai compris de travers ou bien tu t'attendais réellement à ce que la suppression d'un élément d'une liste avec erase() n'invalide pas l'itérateur pointant sur cet élément !?

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Un petit tour au petit jour, entre tes bras... non, c'est pas ca... je recommence

    Un petit tour du coté de la FAQ devrait te donner la réponse
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut
    J'ai un moment pensé qu'on pouvait toujours faire un it++...

  5. #5
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut
    Un petit tour du coté de la FAQ devrait te donner la réponse
    En effet, j'aurais du la relire... cependant, elle n'apporte pas de solution à mon problème : je ne passe en réalité ni la liste ni l'itérator dans la fonction CallFunction.

    En fait, c'est une liste de std::pair<Foncteur,unsigned int> et CallFunction est en réalité it->first.

    Or, il se trouve que Foncteur possède l'id associé au foncteur et va le supprimer de la liste... (l'id étant l'unsigned int de la pair).

  6. #6
    Expert éminent sénior

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 031
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 031
    Points : 11 476
    Points
    11 476
    Billets dans le blog
    11
    Par défaut
    Euh... Je ne suis pas sûr de la bonne logique de l'élément qui modifie son conteneur... il y a peut-etre un problème de design qui se cache derrière tout ça. Au pire tu fais que ta fonction renvoie un booléen si on doit supprimer l'élément courant et tu fais la suppression dans la fonction contenant ta boucle (pas forcément dans la boucle, à toi de voir)
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  7. #7
    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
    Citation Envoyé par NoIdea Voir le message
    J'ai un moment pensé qu'on pouvait toujours faire un it++...
    Oups désolé, j'étais pas trop réveillé, je viens tout juste de comprendre le problème
    La seule solution qui me vient à l'esprit c'est de stocker l'itérateur suivant avant d'appeler CallFunction en se servant du fait que justement les itérateurs d'une liste ne sont jamais invalidés (sauf celui qui pointe vers l'élement qu'on vient de supprimer bien sur) .

    Donc remplacer le for par un while :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef std::list<...>::iterator It;
    It it = l.begin();
    while(it != l.end())
    {
       It next = it++;   
       CallFunction(it,l,...);
       it = next; // next est toujours valide
    }

  8. #8
    Membre actif

    Profil pro
    Inscrit en
    Avril 2010
    Messages
    356
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 356
    Points : 206
    Points
    206
    Par défaut
    Très bonne idée ! Malheureusement j'ai déjà une autre solution (de plus, si dans le Foncteur on efface it next et non pas it, sa marche pas) :

    Vu que l'utilisateur est obligé de passer par ma classe pour supprimer la pair, j'ai rajouter l'itérateur directement dans la classe et non juste dans la fonction. Comme sa, quand l'utilisateur appel Remove, remove peut modifier l'iterateur.

Discussions similaires

  1. Constructeur par copie et std::list
    Par Captain_JS dans le forum SL & STL
    Réponses: 5
    Dernier message: 13/12/2005, 19h15
  2. [C++][std::list] Reinterpret cast
    Par chronos dans le forum SL & STL
    Réponses: 7
    Dernier message: 18/08/2005, 17h04
  3. [dev-C++]std::list<tree_node<T>*> iterator;
    Par jmv dans le forum Dev-C++
    Réponses: 7
    Dernier message: 06/05/2005, 13h14
  4. acceder au n iéme element d'une liste std::list
    Par sorari dans le forum SL & STL
    Réponses: 4
    Dernier message: 23/03/2005, 15h21
  5. [std::list][find_if] problème avec mes foncteurs
    Par n!co dans le forum SL & STL
    Réponses: 12
    Dernier message: 04/02/2005, 11h56

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