C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Vector et erase
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Michaël Delva
Guest





PostPosted: Mon Feb 23, 2004 11:00 am    Post subject: Vector et erase Reply with quote



Bonjour à tous,

quand je parcours un vecteur à l'aide d'une boucle for, et qu'un élément
de ce vecteur doit être supprimé, est-ce que faire un erase() de
l'itérateur correspondant va affecter la suite de ma boucle? Ex:

for (std::vector<int>::const_iterator ite = vect.begin(); ite !=
vect.end(); ++ite)
if (*ite == Cool
vect.erase(*ite);

Après le erase(*ite), est-ce que c'est bien l'élément "après" qui va être
analysé?

J'espère m'être bien fait comprendre...

Merci d'avance
Back to top
Nicolas
Guest





PostPosted: Mon Feb 23, 2004 11:14 am    Post subject: Re: Vector et erase Reply with quote



ca dépend de l'implementation et du type d'objet pointé par l'iterateur.

il faut voir si dans l'implementation du vector<> (dans le man) le fait
d'effacer un element invalide l'iterateur.

en général, oui.
en gros:
v.erase(*iter);
*iter = 10; ca plante !

pour eviter ce genre de question, il faut préparer une iteration +1 :

ci = v.begin();
cn = ci++;
if (*ci == val)
v.erase(*ci);
ci = cn;
else
ci = cn;
cn++;
....

et la c'est clair ? ;-)

Back to top
Franck Branjonneau
Guest





PostPosted: Mon Feb 23, 2004 11:36 am    Post subject: Re: Vector et erase Reply with quote



"Michaël Delva" <zoubidaman (AT) hotmail (DOT) com> écrivait:

Quote:
Bonjour à tous,

Bonjour,

Quote:
quand je parcours un vecteur à l'aide d'une boucle for, et qu'un
élément de ce vecteur doit être supprimé, est-ce que faire un
erase() de l'itérateur correspondant va affecter la suite de ma
boucle?

Sans aucun doute. vector<>::erase(it) détruis l'élément désigné par it
et retourne un itérateur sur l'élément qui suivait it avant sa
destruction.

Quote:
J'espère m'être bien fait comprendre...

Très bien.
--
Franck Branjonneau <fasbjx (AT) free (DOT) fr>

Back to top
Fabien LE LEZ
Guest





PostPosted: Mon Feb 23, 2004 11:57 am    Post subject: Re: Vector et erase Reply with quote

On Mon, 23 Feb 2004 12:14:07 +0100, Nicolas <nicolas.belan (AT) tele2 (DOT) fr>
wrote:

Quote:
il faut voir si dans l'implementation du vector<> (dans le man) le fait
d'effacer un element invalide l'iterateur.

Je confirme que c'est oui : une modification du nombre d'éléments d'un
std::vector<> invalide[*] tous les itérateurs sur des éléments de ce
vector<>. Ta solution ne fonctionne donc pas non plus.


[*] Plus précisément, on n'est pas sûr qu'ils sont invalidés, mais
comme la possibilité existe, on ne peut pas prendre le risque.

--
;-)

Back to top
Guillaume Brocker
Guest





PostPosted: Mon Feb 23, 2004 12:39 pm    Post subject: Re: Vector et erase Reply with quote

Franck Branjonneau wrote:

Quote:
Sans aucun doute. vector<>::erase(it) détruis l'élément désigné par it
et retourne un itérateur sur l'élément qui suivait it avant sa
destruction.

Pour revenir à l'exemple de départ, on peut le transfomer comme suit:

std::vector<int>::iterator ite = vect.begin();

for(;Wink
{
if( ite != vect.end() )
{
if( *ite != 8 )
{
ite = vect.erase( ite );
}
else
{
ite++;
}
}
else
{
break;
}
}

--
Guillaume Brocker

Back to top
Jean-Marc Bourguet
Guest





PostPosted: Mon Feb 23, 2004 12:53 pm    Post subject: Re: Vector et erase Reply with quote

Guillaume Brocker <guillaume.brocker (AT) ircad (DOT) u-strasbg.fr> writes:

Quote:
Franck Branjonneau wrote:

Sans aucun doute. vector<>::erase(it) détruis l'élément désigné par it
et retourne un itérateur sur l'élément qui suivait it avant sa
destruction.

Pour revenir à l'exemple de départ, on peut le transfomer comme suit:

std::vector<int>::iterator ite = vect.begin();

for(;Wink
{
if( ite != vect.end() )
{
if( *ite != 8 )
{
ite = vect.erase( ite );
}
else
{
ite++;
}
}
else
{
break;
}
}

Et pourquoi ne pas utiliser un while plutot que la structure etrange

for(;Wink {
if (cond) {
...
} else {
break;
}

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Back to top
Manuel
Guest





PostPosted: Mon Feb 23, 2004 12:56 pm    Post subject: Re: Vector et erase Reply with quote

"Michaël Delva" <zoubidaman (AT) hotmail (DOT) com> a écrit dans le message de
news:Xns94987A185378Ezoubidamanhotmailcom (AT) 212 (DOT) 27.42.69...
Quote:
Bonjour à tous,

quand je parcours un vecteur à l'aide d'une boucle for, et qu'un élément
de ce vecteur doit être supprimé, est-ce que faire un erase() de
l'itérateur correspondant va affecter la suite de ma boucle? Ex:

for (std::vector<int>::const_iterator ite = vect.begin(); ite !=
vect.end(); ++ite)
if (*ite == Cool
vect.erase(*ite);

Après le erase(*ite), est-ce que c'est bien l'élément "après" qui va être
analysé?

J'espère m'être bien fait comprendre...

Merci d'avance

Ca ne marchera pas comme ça.
L'itérateur n'est plus valide après vect.erase().

AMHA, ce serait mieux d'écrire :

std::vector<int>::const_iterator ite = vect.begin();
while (ite != vect.end())
if (*ite == Cool
vect.erase(*ite++);

Mais je n'en suis pas certain.
Une meilleure solution serait d'utiliser std::remove_if :

inline bool egale_huit(int n) { return (8 == n); }
// ou avec un template, un objet fonction, ... c'est selon le besoin.
vect.erase(std::remove_if(vect.begin(), vect.end(), egale_huit),
vect.end());

En espérant que ça aidera. :-)

--

- Manuel
to reply, swap the name with the domain.



Back to top
Franck Branjonneau
Guest





PostPosted: Mon Feb 23, 2004 1:08 pm    Post subject: Re: Vector et erase Reply with quote

Jean-Marc Bourguet <jm (AT) bourguet (DOT) org> écrivait:

Quote:
Guillaume Brocker <guillaume.brocker (AT) ircad (DOT) u-strasbg.fr> writes:

Franck Branjonneau wrote:

Sans aucun doute. vector<>::erase(it) détruis l'élément désigné
par it et retourne un itérateur sur l'élément qui suivait it
avant sa destruction.

Pour revenir à l'exemple de départ, on peut le transfomer comme
suit:

[ une horrible boucle for ]

Et pourquoi ne pas utiliser un while plutot que la structure etrange

for(;Wink {
if (cond) {
...
} else {
break;
}

Ou alors :

vect.erase(std::remove_if(vect.begin(), vect.end(),
std::bind2nd(std::equal_to< int >(), 5)), vect.end());
--
Franck Branjonneau <fasbjx (AT) free (DOT) fr>

Back to top
Alain Migeon
Guest





PostPosted: Mon Feb 23, 2004 2:50 pm    Post subject: Re: Vector et erase Reply with quote

In article <Xns94987A185378Ezoubidamanhotmailcom (AT) 212 (DOT) 27.42.69>,
[email]zoubidaman (AT) hotmail (DOT) com[/email] says...
Quote:
Bonjour à tous,

quand je parcours un vecteur à l'aide d'une boucle for, et qu'un élément
de ce vecteur doit être supprimé, est-ce que faire un erase() de
l'itérateur correspondant va affecter la suite de ma boucle? Ex:

for (std::vector<int>::const_iterator ite = vect.begin(); ite !=
vect.end(); ++ite)
if (*ite == Cool
vect.erase(*ite);

Après le erase(*ite), est-ce que c'est bien l'élément "après" quiva être
analysé?

J'espère m'être bien fait comprendre...

Merci d'avance

Une solution sûre consiste à mettre les itérateurs des éléments que tu
veux supprimer dans un autre vecteur. Et ensuite de parcourir ce
vecteur.

Alain

Exemple :


#include <vector>
using std::vector;

typedef std::vector <int> VInt;
typedef std::vector <VInt::iterator> VItInt;

int main ()
{
VInt vInt;
VInt::iterator itInt;

VItInt vItInt;
VItInt::iterator itItInt;

// ...
// remplissage de vInt.
// ...

for (itInt = vInt.begin (); itInt != vInt.end (); ++ itInt)
{
if (*itInt == Cool
vItInt.push_back (itInt);
}

for (itItInt = vItInt.begin (); itItInt != vItInt.end (); ++ itItInt)
vInt.erase (*itItInt);

vItInt.clear ();
}



Back to top
Jean-Marc Bourguet
Guest





PostPosted: Mon Feb 23, 2004 2:56 pm    Post subject: Re: Vector et erase Reply with quote

Alain Migeon <agm (AT) dk (DOT) rovsing> writes:

Quote:
In article <Xns94987A185378Ezoubidamanhotmailcom (AT) 212 (DOT) 27.42.69>,
[email]zoubidaman (AT) hotmail (DOT) com[/email] says...
Bonjour à tous,

quand je parcours un vecteur à l'aide d'une boucle for, et qu'un élément
de ce vecteur doit être supprimé, est-ce que faire un erase() de
l'itérateur correspondant va affecter la suite de ma boucle? Ex:

for (std::vector<int>::const_iterator ite = vect.begin(); ite !=
vect.end(); ++ite)
if (*ite == Cool
vect.erase(*ite);

Après le erase(*ite), est-ce que c'est bien l'élément "après" qui va être
analysé?

J'espère m'être bien fait comprendre...

Merci d'avance

Une solution sûre consiste à mettre les itérateurs des éléments que tu
veux supprimer dans un autre vecteur. Et ensuite de parcourir ce
vecteur.


Quote:
Alain

Exemple :


#include <vector
using std::vector;

typedef std::vector typedef std::vector <VInt::iterator> VItInt;

int main ()
{
VInt vInt;
VInt::iterator itInt;

VItInt vItInt;
VItInt::iterator itItInt;

// ...
// remplissage de vInt.
// ...

for (itInt = vInt.begin (); itInt != vInt.end (); ++ itInt)
{
if (*itInt == Cool
vItInt.push_back (itInt);
}

for (itItInt = vItInt.begin (); itItInt != vItInt.end (); ++ itItInt)
vInt.erase (*itItInt);

vItInt.clear ();
}


Pas sur du tout tel qu'ecrit: les iterateurs d'un vecteur (pointant
apres l'iterateur) sont invalides apres tout effacement. Si t'iteres
a l'envers par contre, c'est correct.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Back to top
Alain Migeon
Guest





PostPosted: Mon Feb 23, 2004 3:05 pm    Post subject: Re: Vector et erase Reply with quote

In article <pxbsmh14zew.fsf (AT) news (DOT) bourguet.org>, [email]jm (AT) bourguet (DOT) org[/email] says...
Quote:
Alain Migeon <agm (AT) dk (DOT) rovsing> writes:

In article <Xns94987A185378Ezoubidamanhotmailcom (AT) 212 (DOT) 27.42.69>,
[email]zoubidaman (AT) hotmail (DOT) com[/email] says...
Bonjour à tous,

quand je parcours un vecteur à l'aide d'une boucle for, et qu'un élément
de ce vecteur doit être supprimé, est-ce que faire un erase() de
l'itérateur correspondant va affecter la suite de ma boucle? Ex:

for (std::vector<int>::const_iterator ite = vect.begin(); ite !=
vect.end(); ++ite)
if (*ite == Cool
vect.erase(*ite);

Après le erase(*ite), est-ce que c'est bien l'élément "après"qui va être
analysé?

J'espère m'être bien fait comprendre...

Merci d'avance

Une solution sûre consiste à mettre les itérateurs des éléments que tu
veux supprimer dans un autre vecteur. Et ensuite de parcourir ce
vecteur.


Alain

Exemple :


#include <vector
using std::vector;

typedef std::vector typedef std::vector <VInt::iterator> VItInt;

int main ()
{
VInt vInt;
VInt::iterator itInt;

VItInt vItInt;
VItInt::iterator itItInt;

// ...
// remplissage de vInt.
// ...

for (itInt = vInt.begin (); itInt != vInt.end (); ++ itInt)
{
if (*itInt == Cool
vItInt.push_back (itInt);
}

for (itItInt = vItInt.begin (); itItInt != vItInt.end (); ++ itItInt)
vInt.erase (*itItInt);

vItInt.clear ();
}


Pas sur du tout tel qu'ecrit: les iterateurs d'un vecteur (pointant
apres l'iterateur) sont invalides apres tout effacement. Si t'iteres
a l'envers par contre, c'est correct.

Mea culpa.

J'ai écrit trop vite.
C'est la méthode que j'utilise pour supprimer les éléments d'un map.
Dans ce cas un itérateur reste valide jusqu'à sa suppression.

Alain

Back to top
Nicolas
Guest





PostPosted: Mon Feb 23, 2004 3:36 pm    Post subject: Re: Vector et erase Reply with quote

Quote:

il faut voir si dans l'implementation du vector<> (dans le man) le fait
d'effacer un element invalide l'iterateur.

Je confirme que c'est oui : une modification du nombre d'éléments d'un
std::vector<> invalide[*] tous les itérateurs sur des éléments de ce
vector<>. Ta solution ne fonctionne donc pas non plus.

pas forcément ... mais un peu qd meme ...
dans un cas ca marche, mais je n'ai pas tout dit (mea culpa)
si on part de la fin, et qu'on inverse la boucle (avec un reverse_iterator,
ou for(ci = end(); ci != begin(); ci--)
ca marche (avec les vector des stl sgi ...)

donc, pour etre tres précis, un erase invalide tous les iterateurs qui
pointent sur des elements qui sont après l'iterateur en erase() (simple non
?)

c'est censé retourner un iterateur. Mais d'experience, j'ai vu des STL qui
ne retournent pas l'iterateur ...

Back to top
Fabien LE LEZ
Guest





PostPosted: Mon Feb 23, 2004 3:38 pm    Post subject: Re: Vector et erase Reply with quote

On Mon, 23 Feb 2004 15:50:37 +0100, Alain Migeon <agm (AT) dk (DOT) rovsing>
wrote:

Quote:
Content-Transfer-Encoding: quoted-printable

Peux-tu éviter le quoted-printable sur Usenet ? C'est en effet assez
illisible (du style, "Une solution s=FBre consiste =E0 mettre les
it=E9rateurs des =E9l=E9ments") Sad
Merci d'avance...

--
;-)

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Mon Feb 23, 2004 5:20 pm    Post subject: Re: Vector et erase Reply with quote

Nicolas <nicolas.belan (AT) tele2 (DOT) fr> wrote


Quote:
ca dépend de l'implementation et du type d'objet pointé par
l'iterateur.

Pas du tout.

Quote:
il faut voir si dans l'implementation du vector<> (dans le man) le
fait d'effacer un element invalide l'iterateur.

En général, le fait de supprimer un élément d'une collection invalide
tout itérateur qui désigne l'élément supprimé. Étant donné la façon
comment fonctionne la STL, c'est difficile à voir comment ça pourrait
être autrement.

Dans le cas de std::vector, le fait de supprimer un élément invalide non
seulement les itérateurs qui désigne l'élément, mais tous les itérateurs
qui le suivent.

Quote:
en général, oui.
en gros:
v.erase(*iter);
*iter = 10; ca plante !

pour eviter ce genre de question, il faut préparer une iteration +1 :

ci = v.begin();
cn = ci++;
if (*ci == val)
v.erase(*ci);
ci = cn;
else
ci = cn;
cn++;
...

et la c'est clair ? Wink

Selon la norme, ça ne marche pas non plus.

En fait, vector<>::erase renvoie un itérateur à l'élément qui suit le
dernier élément supprimé. On pourrait donc écrire :

std::vector<T>::iterator current = v.begin() ;
while ( current != v.end() ) {
if ( *current == val ) {
current = v.erase( current ) ;
} else {
++ current ;
}
}

Alternativement, on pourrait écrire :

v.erase( std::remove( v.begin(), v.end(), val ), v.end() ) ;

--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

Back to top
Nicolas
Guest





PostPosted: Tue Feb 24, 2004 11:50 am    Post subject: Re: Vector et erase Reply with quote

[snip]
Quote:
ca dépend de l'implementation et du type d'objet pointé par
l'iterateur.

Pas du tout.


malheureusement, je confirme. Ca depend bien de l'implementation. J'ai eu
affaire avec des erase defini dans une STL, mais pas dans une autre (entre
BSDi et Sun par exemple), ou bien dont les arguments n'etaient pas dans le
meme ordre (et oui ...) ou encore ou la doc ne spécifié aucun retour alors
que l'implementationr retournait un iterateur.
quand au type d'objet pointé, c'est un abus de langage; je veux dire
vector, map, deque, list ... bref les objets qui implementent un erase non
pas tous le meme comportement.

[snip]

et si on veut garder un for, il suffit d'inverser la boucle .


bref ...

NB

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.