Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

ajout d'elements dasn un vector que l'on parcours

7 réponses
Avatar
JBB
Bonjour
voilà je fais un code du genre

vector < Truc> m_liste;
vector < Truc>::iterator it = m_liste.being();
while (it != m_liste.end()){
if (...){
it = m_liste.erase(it);
}else {
it++;
}
if(...){
m_liste.push_back(nouveauTruc);
}
}

et je me demande si cela va marcher.
En fait je supprime certains element sous certaines conditions et j'en duplique d'autres.

Autant je ne me fais pas de soucis sur le erase par contre est ce que le push_back ne peut pas mettre le souk
(notamment si it est en fait un pointeur et que le push_back peut induire une reallocation).
Sinon comment je fais?
Je n'ai pas forcement besoin de mettre nouveauTruc à la fin, mais forcement apres it pourqu'il soit traiter dans la boucle.

7 réponses

Avatar
Fabien LE LEZ
On Wed, 25 Apr 2007 12:34:20 +0200, JBB :

par contre est ce que le push_back ne peut pas mettre le souk


Si, il invalide l'itérateur.
Les façons de s'en sortir :
- remplacer vector<> par list<>
- ne pas faire les modifications in-situ, mais dans un tableau
temporaire :


vector < Truc> m_liste;
// ici, remplissage, j'imagine

vector<Truc> temp;

for (vector < Truc>::const_iterator it = m_liste.being();
it != m_liste.end(); ++it)
{
if (...){
// Ne rien faire
}else {
temp.push_back (*it);
}
if(...){
temp.push_back(nouveauTruc);
}
}

temp.swap (m_liste);

Note : je crois bien que ce code n'est pas équivalent au tien, car il
n'insère pas les éléments dans le même ordre. À toi de le modifier
(peut-être avec deux boucles ?) pour qu'il convienne à ton cahier des
charges.

Avatar
JBB
On Wed, 25 Apr 2007 12:34:20 +0200, JBB :

par contre est ce que le push_back ne peut pas mettre le souk


Si, il invalide l'itérateur.
Les façons de s'en sortir :
- remplacer vector<> par list<>
- ne pas faire les modifications in-situ, mais dans un tableau
temporaire :


vector < Truc> m_liste;
// ici, remplissage, j'imagine

vector<Truc> temp;

for (vector < Truc>::const_iterator it = m_liste.being();
it != m_liste.end(); ++it)
{
if (...){
// Ne rien faire
}else {
temp.push_back (*it);
}
if(...){
temp.push_back(nouveauTruc);
}
}

temp.swap (m_liste);

Note : je crois bien que ce code n'est pas équivalent au tien, car il
n'insère pas les éléments dans le même ordre. À toi de le modifier
(peut-être avec deux boucles ?) pour qu'il convienne à ton cahier des
charges.

je vais utiliser une liste, ca me parait plus adequat.

Merci


Avatar
Fabien LE LEZ
Évite de recopier tout le message juste pour rajouter une ligne :-(
Je t'invite à lire attentivement ce document :
http://www.usenet-fr.net/fr.usenet.reponses/usenet/repondre-sur-usenet.html
Avatar
Sylvain Defresne
Autant je ne me fais pas de soucis sur le erase par contre est ce que le
push_back ne peut pas mettre le souk
(notamment si it est en fait un pointeur et que le push_back peut
induire une reallocation).
Sinon comment je fais?


Tu peux utiliser des indices au lieu d'itérateurs pour ta boucle. Ils
ont l'avantage de ne pas être invalidés par une réallocation. Cela
donnerait quelque chose du genre :

vector< Truc > m_liste;
for (size_t i = 0, m_liste_size = m_liste.size(); i < size; /* pass */)
{
if (...)
{
m_liste.erase(m_liste.begin() + i);
-- m_liste_size;
}
else
{
++i;
}

if (...)
{
m_liste.push_back(Truc(...));
++ m_liste_size;
}
}

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

Avatar
James Kanze
On Apr 25, 12:34 pm, JBB wrote:

voilà je fais un code du genre

vector < Truc> m_liste;
vector < Truc>::iterator it = m_liste.being();
while (it != m_liste.end()){
if (...){
it = m_liste.erase(it);
}else {
it++;
}
if(...){
m_liste.push_back(nouveauTruc);
}

}

et je me demande si cela va marcher.

En fait je supprime certains element sous certaines conditions
et j'en duplique d'autres.

Autant je ne me fais pas de soucis sur le erase par contre est
ce que le push_back ne peut pas mettre le souk (notamment si
it est en fait un pointeur et que le push_back peut induire
une reallocation).


En effet. push_back est défini en termes d'insert, et
l'insertion :
-- invalide tous les itérateurs derrière le point d'insertion,
et
-- invalide tous les itérateurs, où qu'ils pointent, si la
nouvelle capacité est strictement supérieur à l'ancienne.

Sinon comment je fais?


Il y a plusieurs solutions. Si tu peut établir un maximum pour
le nombre d'insertions, quelque chose du genre :

m_list.reserve( m_list.size() * 2 ) ;

avant de chercher l'itérateur ferait l'affaire. (m_list.size()*2
suppose qu'il y aurait jamais plus d'une insertion par
itération.) C'est ce qu'il y a de plus simple à implémenter,
mais je ne sais pas si c'est très transparent pour le lecteur ;
je mettrais au moins un commentaire.

Sinon, on peut transformer les itérateurs de vector en indices,
et vice versa. À la place de push_back, donc :

size_t offset = it - m_list.begin() ;
m_list.push_back( ... ) ;
it = m_list.begin() + offset ;

Plus généralement, on peut travailler directement avec des
indices :

size_t i = 0 ;
while ( i != m_liste.size() ) {
if ( ... ) {
m_liste.erase( m_liste.begin() + i ) ;
} else {
++ i ;
}
if ( ... ) {
m_liste.push_back( ... ) ;
}
}

Enfin, il existe d'autres types de collections, avec d'autres
règles en ce qui concerne la validité des itérateurs.

--
James Kanze (GABI Software) email:
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
Youri
Bonjour,


[...]
Enfin, il existe d'autres types de collections, avec d'autres
règles en ce qui concerne la validité des itérateurs.


Où peut-on trouver les règles concernant la validité des itérateurs
selon les opérations que l'on applique ? Est-ce qu'elles sont décrites
de manière lisible quelque part ailleurs que dans la norme ?

--
Youri

Avatar
James Kanze
On Apr 27, 8:52 am, Youri wrote:

[...]

Enfin, il existe d'autres types de collections, avec d'autres
règles en ce qui concerne la validité des itérateurs.


Où peut-on trouver les règles concernant la validité des itérateu rs
selon les opérations que l'on applique ? Est-ce qu'elles sont décrites
de manière lisible quelque part ailleurs que dans la norme ?


Bonne question. Moi, j'ai une copie de la norme en ligne, et
c'est là où je régarde. Mais « lisible » n'est pas exactement
le mot que je choisirais pour la décrire.

Sans avoir vérifier, j'aurais espéré que les sites de Dinkumware
ou de SGI avait de telles informations.

--
James Kanze (GABI Software) email:
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