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 == 8)
vect.erase(*ite);
Après le erase(*ite), est-ce que c'est bien l'élément "après" qui va être
analysé?
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 ...
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 ...
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 ...
Fabien LE LEZ
On Mon, 23 Feb 2004 15:50:37 +0100, Alain Migeon wrote:
Content-Transfer-Encoding: quoted-printable
Peux-tu éviter le quoted-printable sur Usenet ? C'est en effet assez illisible (du style, "Une solution sûre consiste à mettre les itérateurs des éléments") :-( Merci d'avance...
-- ;-)
On Mon, 23 Feb 2004 15:50:37 +0100, Alain Migeon <agm@dk.rovsing>
wrote:
Content-Transfer-Encoding: quoted-printable
Peux-tu éviter le quoted-printable sur Usenet ? C'est en effet assez
illisible (du style, "Une solution sûre consiste à mettre les
itérateurs des éléments") :-(
Merci d'avance...
On Mon, 23 Feb 2004 15:50:37 +0100, Alain Migeon wrote:
Content-Transfer-Encoding: quoted-printable
Peux-tu éviter le quoted-printable sur Usenet ? C'est en effet assez illisible (du style, "Une solution sûre consiste à mettre les itérateurs des éléments") :-( Merci d'avance...
-- ;-)
kanze
Nicolas wrote in message news:...
ca dépend de l'implementation et du type d'objet pointé par l'iterateur.
Pas du tout.
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.
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 ? ;-)
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: 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
Nicolas <nicolas.belan@tele2.fr> wrote in message
news:<mqhuqtq2wcju.1r3eizm9r4onf.dlg@40tude.net>...
ca dépend de l'implementation et du type d'objet pointé par
l'iterateur.
Pas du tout.
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.
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 ? ;-)
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@gabi-soft.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
ca dépend de l'implementation et du type d'objet pointé par l'iterateur.
Pas du tout.
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.
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 ? ;-)
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: 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
Nicolas
[snip]
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
[snip]
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 .
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
kanze
Nicolas wrote in message news:<164rc974k1rvs$.q7nl0u8f0c6a$...
[snip]
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.
Il y a des bibliothèques non-standard qui font autrement que la bibliothèque standard. Certaines ressemblent fort à la bibliothèque standard, mais avec certains écarts. AMHA, ceux-là sont à éviter -- il n'y a que deux raisons pour se servir d'autre chose que la bibliothèque standard :
- tu as besoin des fonctionnalités non prévues par la bibliothèque standard : des expressions rationnelles, une interface graphique, voire même des itérateurs « classiques » ou des itérateurs « sûrs ».
- ton compilateur ne supporte pas toutes les fonctionnalités nécessaires -- par exemple, des templates membres. DAns ce cas-ci, je m'attendrais à ce que les fonctionnalités présentes soient identiques.
En ce qui concerne la bibliothèque standard, les règles de validité d'un itérateur ne dépend jamais du type d'objet contenu dans la collection.
-- James Kanze GABI Software mailto: 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
Nicolas <nicolas.belan@tele2.fr> wrote in message
news:<164rc974k1rvs$.q7nl0u8f0c6a$.dlg@40tude.net>...
[snip]
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.
Il y a des bibliothèques non-standard qui font autrement que la
bibliothèque standard. Certaines ressemblent fort à la bibliothèque
standard, mais avec certains écarts. AMHA, ceux-là sont à éviter -- il
n'y a que deux raisons pour se servir d'autre chose que la bibliothèque
standard :
- tu as besoin des fonctionnalités non prévues par la bibliothèque
standard : des expressions rationnelles, une interface graphique,
voire même des itérateurs « classiques » ou des itérateurs « sûrs ».
- ton compilateur ne supporte pas toutes les fonctionnalités
nécessaires -- par exemple, des templates membres. DAns ce cas-ci,
je m'attendrais à ce que les fonctionnalités présentes soient
identiques.
En ce qui concerne la bibliothèque standard, les règles de validité d'un
itérateur ne dépend jamais du type d'objet contenu dans la collection.
--
James Kanze GABI Software mailto:kanze@gabi-soft.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
Nicolas wrote in message news:<164rc974k1rvs$.q7nl0u8f0c6a$...
[snip]
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.
Il y a des bibliothèques non-standard qui font autrement que la bibliothèque standard. Certaines ressemblent fort à la bibliothèque standard, mais avec certains écarts. AMHA, ceux-là sont à éviter -- il n'y a que deux raisons pour se servir d'autre chose que la bibliothèque standard :
- tu as besoin des fonctionnalités non prévues par la bibliothèque standard : des expressions rationnelles, une interface graphique, voire même des itérateurs « classiques » ou des itérateurs « sûrs ».
- ton compilateur ne supporte pas toutes les fonctionnalités nécessaires -- par exemple, des templates membres. DAns ce cas-ci, je m'attendrais à ce que les fonctionnalités présentes soient identiques.
En ce qui concerne la bibliothèque standard, les règles de validité d'un itérateur ne dépend jamais du type d'objet contenu dans la collection.
-- James Kanze GABI Software mailto: 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