OVH Cloud OVH Cloud

Effacer un element d'une liste

14 réponses
Avatar
korchkidu
Bonjour,

je parcours une liste et je veux effacer certains elements suivant les
traitements faits plus tot. Comme le fait de faire erase invalide
l'iterateur ca me pose forcement un probleme.

J'ai regarde sur le web mais franchement les solutions proposees sont
pas tres "jolies" je trouve. Vous faites comment vous?

K.

10 réponses

1 2
Avatar
xavier
korchkidu a dit le 10/02/2005 17:48:
Bonjour,

je parcours une liste et je veux effacer certains elements suivant les
traitements faits plus tot. Comme le fait de faire erase invalide
l'iterateur ca me pose forcement un probleme.
J'ai regarde sur le web mais franchement les solutions proposees sont
pas tres "jolies" je trouve. Vous faites comment vous?


j'utilise std::erase_if().

xavier

Avatar
Fabien LE LEZ
On Thu, 10 Feb 2005 17:48:25 +0100, korchkidu :

je parcours une liste et je veux effacer certains elements suivant les
traitements faits plus tot.


Tu peux utiliser la fonction membre remove_if().

Si tu tiens à parcourir ta liste, tu peux faire un truc du style

for (...::iterator i= ma_liste.begin(); i != ma_liste.end();)
{
if (on doit supprimer l'élément)
{
ma_liste.erase (i++);
}
else
{
++i;
}
}


--
;-)

Avatar
Loïc Joly
xavier wrote:

korchkidu a dit le 10/02/2005 17:48:

Bonjour,

je parcours une liste et je veux effacer certains elements suivant les
traitements faits plus tot. Comme le fait de faire erase invalide
l'iterateur ca me pose forcement un probleme.
J'ai regarde sur le web mais franchement les solutions proposees sont
pas tres "jolies" je trouve. Vous faites comment vous?



j'utilise std::erase_if().


Je serais curieux de savoir comment tu implémenterais un tel algorithme
à base d'itérateurs...

--
Loïc


Avatar
xavier
Loïc Joly a dit :
xavier wrote:
j'utilise std::erase_if().



Je serais curieux de savoir comment tu implémenterais un tel algorithme
à base d'itérateurs...


Il m'a fallu du temps pour comprendre ce que tu voulais dire...

Puis j'ai compris. J'ai écris std::erase_if(), alors que je pensais à
std:remove_if(). std::remove_if() est la solution fournie par la STL au
problème de l'OT.

la solution complète ayant une forme similaire à :

! template <typename List, typename Predicate>
! void erase_if(List & v, Predicate p) {
! v.erase(std::remove_if(v.begin(), v.end(), p), v.end());
! }

xavier


Avatar
Fabien LE LEZ
On Thu, 10 Feb 2005 23:08:13 +0100, xavier :

std::remove_if() est la solution fournie par la STL au
problème de l'OT.


A ceci près que std::list<> contient une fonction remove_if()... qui
n'a bien sûr pas le même fonctionnement que std::remove_if(), histoire
de bien compliquer les choses :-/



--
;-)

Avatar
kanze
xavier wrote:
korchkidu a dit le 10/02/2005 17:48:

je parcours une liste et je veux effacer certains elements
suivant les traitements faits plus tot. Comme le fait de
faire erase invalide l'iterateur ca me pose forcement un
probleme. J'ai regarde sur le web mais franchement les
solutions proposees sont pas tres "jolies" je trouve. Vous
faites comment vous?


j'utilise std::erase_if().


Et où est-ce que tu trouves cette fonction ? Je ne la trouve pas
dans ma copie de la norme, et je n'en ai jamais entendu parler
avant.

En passant, la solution classique resemble un peu à :

std::list<T>::iterator i = l.begin() ;
while ( i != l.end() ) {
if ( condition( *i ) ) {
i = l.erase( i ) ;
} else {
++ i ;
}
}

Mais je ne suis pas sÛr d'après le posting initial si le
problème est l'itérateur dans la boucle, ou d'autres itérateurs
qu'il peut y avoir. Pour les autres itérateurs, s'il n'efface
pas l'élément qu'ils désignent, il n'y a pas de problème avec
std::list.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
korchkidu
Fabien LE LEZ wrote:

Si tu tiens à parcourir ta liste, tu peux faire un truc du style

for (...::iterator i= ma_liste.begin(); i!=ma_liste.end )
{
if (on doit supprimer l'élément)
{
ma_liste.erase (i++);
}
else
{
++i;
}
}


Ca me parait un peu moins tire par les cheveux que ce que j'ai vu...

Merci,
K.

Avatar
korchkidu
wrote:


std::list<T>::iterator i = l.begin() ;
while ( i != l.end() ) {
if ( condition( *i ) ) {
i = l.erase( i ) ;
} else {
++ i ;
}
}



Ca me parait etre la solution communement utilisee apparemment...

Merci,
K.

Avatar
Fabien LE LEZ
On 11 Feb 2005 01:48:07 -0800, :

i = l.erase( i ) ;


Tout en faisant attention aux compilos non conformes, pour lesquels
list::erase ne renvoie rien (si, si, ça existe...)


--
;-)

Avatar
Alexandre
bonjour,

if (on doit supprimer l'élément)
{
ma_liste.erase (i++);


donc incrémentation de i après l'appel de erase()... i qui est devenu non
valide...
Je pense qu'une solution (si erase ne renvoie rien) est :
iterator i_temp = i;
++i_temp;
ma_liste.erase(i);
i=i_temp;

1 2