std::list<Cell_handle> i;
...
std::list<Cell_handle>::iterator i,erase_me;
while (i!=in.end()) {
for (int j=0;j<4;j++)
ne serait-ce
que pour approfondir ma compréhension des iterateurs de liste, je me
demande s'il existe une méthode propre de type boucle
std::list<Cell_handle> i;
...
std::list<Cell_handle>::iterator i,erase_me;
while (i!=in.end()) {
for (int j=0;j<4;j++)
ne serait-ce
que pour approfondir ma compréhension des iterateurs de liste, je me
demande s'il existe une méthode propre de type boucle
std::list<Cell_handle> i;
...
std::list<Cell_handle>::iterator i,erase_me;
while (i!=in.end()) {
for (int j=0;j<4;j++)
ne serait-ce
que pour approfondir ma compréhension des iterateurs de liste, je me
demande s'il existe une méthode propre de type boucle
J'avoue que je ne comprends rien à ton code
oups, oui, c'est vrai... Comme d'hab je modifies mon code à la volée
for (int j=0;j<4;j++)
Une autre illustration de ce que je disais au dessus... Dans mon code
i= erase (i);
Ah, bein oui tiens... Je n'avais pas fait attention à la valeur de
J'avoue que je ne comprends rien à ton code
oups, oui, c'est vrai... Comme d'hab je modifies mon code à la volée
for (int j=0;j<4;j++)
Une autre illustration de ce que je disais au dessus... Dans mon code
i= erase (i);
Ah, bein oui tiens... Je n'avais pas fait attention à la valeur de
J'avoue que je ne comprends rien à ton code
oups, oui, c'est vrai... Comme d'hab je modifies mon code à la volée
for (int j=0;j<4;j++)
Une autre illustration de ce que je disais au dessus... Dans mon code
i= erase (i);
Ah, bein oui tiens... Je n'avais pas fait attention à la valeur de
Tout est dit dans le sujet, je cherche la manière élégante de
parcourir une liste en supprimant éventuellement certains éléments.
Mon problème réside essentiellement dans la mauvaise compréhension
que j'ai de la validité des iterateurs lors d'une délétion...
[...]
Depuis, j'ai appris l'existence de remove_if, néanmoins, ne serait-ce
que pour approfondir ma compréhension des iterateurs de liste, je me
demande s'il existe une méthode propre de type boucle (i.e. avec un
while ou un for).
Tout est dit dans le sujet, je cherche la manière élégante de
parcourir une liste en supprimant éventuellement certains éléments.
Mon problème réside essentiellement dans la mauvaise compréhension
que j'ai de la validité des iterateurs lors d'une délétion...
[...]
Depuis, j'ai appris l'existence de remove_if, néanmoins, ne serait-ce
que pour approfondir ma compréhension des iterateurs de liste, je me
demande s'il existe une méthode propre de type boucle (i.e. avec un
while ou un for).
Tout est dit dans le sujet, je cherche la manière élégante de
parcourir une liste en supprimant éventuellement certains éléments.
Mon problème réside essentiellement dans la mauvaise compréhension
que j'ai de la validité des iterateurs lors d'une délétion...
[...]
Depuis, j'ai appris l'existence de remove_if, néanmoins, ne serait-ce
que pour approfondir ma compréhension des iterateurs de liste, je me
demande s'il existe une méthode propre de type boucle (i.e. avec un
while ou un for).
"meow" writes:Tout est dit dans le sujet, je cherche la manière élégante
de parcourir une liste en supprimant éventuellement certains
éléments. Mon problème réside essentiellement dans la
mauvaise compréhension que j'ai de la validité des
iterateurs lors d'une délétion...
[...]
Depuis, j'ai appris l'existence de remove_if, néanmoins, ne
serait-ce que pour approfondir ma compréhension des
iterateurs de liste, je me demande s'il existe une méthode
propre de type boucle (i.e. avec un while ou un for).
J'ai eu besoin de faire ca aussi, je ne suis pas sur de ma
methode mais pour l'instant elle marche:
En gros je sauvegarde l'iterator dans un 2eme iterator fait
pour ca, et j'increment l'iterator que j'utilise dans la
boucle.
Apres cela je supprime l'iterator de sauvegarde selon une
condition, et je peux quand meme continuer a "iterer" puisque
j'ai juste supprime une sauvegarde.
Je suis neanmoins pas sur que ce code soit sur :)
<code>
[...]
void Module::Free(basic_string <char> mod)
{
list <Module *>::iterator it;
list <Module *>::iterator save;
it = Module::linked.begin();
while (it != Module::linked.end())
{
cout << *it << endl;
save = it++;
if ((*save)->name == mod)
delete *save;
}
}
</code>
"meow" <schwarz.ben@gmail.com> writes:
Tout est dit dans le sujet, je cherche la manière élégante
de parcourir une liste en supprimant éventuellement certains
éléments. Mon problème réside essentiellement dans la
mauvaise compréhension que j'ai de la validité des
iterateurs lors d'une délétion...
[...]
Depuis, j'ai appris l'existence de remove_if, néanmoins, ne
serait-ce que pour approfondir ma compréhension des
iterateurs de liste, je me demande s'il existe une méthode
propre de type boucle (i.e. avec un while ou un for).
J'ai eu besoin de faire ca aussi, je ne suis pas sur de ma
methode mais pour l'instant elle marche:
En gros je sauvegarde l'iterator dans un 2eme iterator fait
pour ca, et j'increment l'iterator que j'utilise dans la
boucle.
Apres cela je supprime l'iterator de sauvegarde selon une
condition, et je peux quand meme continuer a "iterer" puisque
j'ai juste supprime une sauvegarde.
Je suis neanmoins pas sur que ce code soit sur :)
<code>
[...]
void Module::Free(basic_string <char> mod)
{
list <Module *>::iterator it;
list <Module *>::iterator save;
it = Module::linked.begin();
while (it != Module::linked.end())
{
cout << *it << endl;
save = it++;
if ((*save)->name == mod)
delete *save;
}
}
</code>
"meow" writes:Tout est dit dans le sujet, je cherche la manière élégante
de parcourir une liste en supprimant éventuellement certains
éléments. Mon problème réside essentiellement dans la
mauvaise compréhension que j'ai de la validité des
iterateurs lors d'une délétion...
[...]
Depuis, j'ai appris l'existence de remove_if, néanmoins, ne
serait-ce que pour approfondir ma compréhension des
iterateurs de liste, je me demande s'il existe une méthode
propre de type boucle (i.e. avec un while ou un for).
J'ai eu besoin de faire ca aussi, je ne suis pas sur de ma
methode mais pour l'instant elle marche:
En gros je sauvegarde l'iterator dans un 2eme iterator fait
pour ca, et j'increment l'iterator que j'utilise dans la
boucle.
Apres cela je supprime l'iterator de sauvegarde selon une
condition, et je peux quand meme continuer a "iterer" puisque
j'ai juste supprime une sauvegarde.
Je suis neanmoins pas sur que ce code soit sur :)
<code>
[...]
void Module::Free(basic_string <char> mod)
{
list <Module *>::iterator it;
list <Module *>::iterator save;
it = Module::linked.begin();
while (it != Module::linked.end())
{
cout << *it << endl;
save = it++;
if ((*save)->name == mod)
delete *save;
}
}
</code>
[...]void Module::Free(basic_string <char> mod)
{
list <Module *>::iterator it;
list <Module *>::iterator save;
it = Module::linked.begin();
Pourquoi séparer l'initialisation de la déclaration ? Et
pourquoi déclarer la variable save ici, et non dans la boucle ?
while (it != Module::linked.end())
{
cout << *it << endl;
save = it++;
if ((*save)->name == mod)
delete *save;
Ce qui supprime l'objet, mais laisse le pointeur (invalid) dans
la liste. Ce qui est formellement un comportement indéfini, tout
de suite, et risque fort de ne pas marcher réelement dès le
prochain parcours de la liste, puisque tu n'as aucun moyen à
savoir quels pointeurs sont valides.}
}
</code>
[...]
void Module::Free(basic_string <char> mod)
{
list <Module *>::iterator it;
list <Module *>::iterator save;
it = Module::linked.begin();
Pourquoi séparer l'initialisation de la déclaration ? Et
pourquoi déclarer la variable save ici, et non dans la boucle ?
while (it != Module::linked.end())
{
cout << *it << endl;
save = it++;
if ((*save)->name == mod)
delete *save;
Ce qui supprime l'objet, mais laisse le pointeur (invalid) dans
la liste. Ce qui est formellement un comportement indéfini, tout
de suite, et risque fort de ne pas marcher réelement dès le
prochain parcours de la liste, puisque tu n'as aucun moyen à
savoir quels pointeurs sont valides.
}
}
</code>
[...]void Module::Free(basic_string <char> mod)
{
list <Module *>::iterator it;
list <Module *>::iterator save;
it = Module::linked.begin();
Pourquoi séparer l'initialisation de la déclaration ? Et
pourquoi déclarer la variable save ici, et non dans la boucle ?
while (it != Module::linked.end())
{
cout << *it << endl;
save = it++;
if ((*save)->name == mod)
delete *save;
Ce qui supprime l'objet, mais laisse le pointeur (invalid) dans
la liste. Ce qui est formellement un comportement indéfini, tout
de suite, et risque fort de ne pas marcher réelement dès le
prochain parcours de la liste, puisque tu n'as aucun moyen à
savoir quels pointeurs sont valides.}
}
</code>
"kanze" writes:
while (it != Module::linked.end())
{
cout << *it << endl;
save = it++;
if ((*save)->name == mod)
delete *save;
Ce qui supprime l'objet, mais laisse le pointeur (invalid)
dans la liste. Ce qui est formellement un comportement
indéfini, tout de suite, et risque fort de ne pas marcher
réelement dès le prochain parcours de la liste, puisque tu
n'as aucun moyen à savoir quels pointeurs sont valides.}
}
</code>
Si tu veux parler du pointeur dans la liste pointant vers le
"Module *" qui vient de se faire delete, non, car le
destructeur de cet object se charge de faire un FreeLibrary et
de s'enlever lui-meme de la liste :)
Et Module::Free() est statique donc l'objet qu'on delete ne
peut pas etre le contexte dans lequel est apelle cette
fonction membre puisqu'il y n'y a pas de "this" :)
<code>
Module::~Module()
{
cout << this << " Module::~Module()" << endl;
cout << name << ": freeing..." << endl;
if (hProcFree)
hProcFree();
FreeLibrary(hinstLib);
linked.remove(this);
}
</code>
Si tu parles de l'invalidite d'un autre pointeur explicite
plus stp :)
"kanze" <kanze@gabi-soft.fr> writes:
while (it != Module::linked.end())
{
cout << *it << endl;
save = it++;
if ((*save)->name == mod)
delete *save;
Ce qui supprime l'objet, mais laisse le pointeur (invalid)
dans la liste. Ce qui est formellement un comportement
indéfini, tout de suite, et risque fort de ne pas marcher
réelement dès le prochain parcours de la liste, puisque tu
n'as aucun moyen à savoir quels pointeurs sont valides.
}
}
</code>
Si tu veux parler du pointeur dans la liste pointant vers le
"Module *" qui vient de se faire delete, non, car le
destructeur de cet object se charge de faire un FreeLibrary et
de s'enlever lui-meme de la liste :)
Et Module::Free() est statique donc l'objet qu'on delete ne
peut pas etre le contexte dans lequel est apelle cette
fonction membre puisqu'il y n'y a pas de "this" :)
<code>
Module::~Module()
{
cout << this << " Module::~Module()" << endl;
cout << name << ": freeing..." << endl;
if (hProcFree)
hProcFree();
FreeLibrary(hinstLib);
linked.remove(this);
}
</code>
Si tu parles de l'invalidite d'un autre pointeur explicite
plus stp :)
"kanze" writes:
while (it != Module::linked.end())
{
cout << *it << endl;
save = it++;
if ((*save)->name == mod)
delete *save;
Ce qui supprime l'objet, mais laisse le pointeur (invalid)
dans la liste. Ce qui est formellement un comportement
indéfini, tout de suite, et risque fort de ne pas marcher
réelement dès le prochain parcours de la liste, puisque tu
n'as aucun moyen à savoir quels pointeurs sont valides.}
}
</code>
Si tu veux parler du pointeur dans la liste pointant vers le
"Module *" qui vient de se faire delete, non, car le
destructeur de cet object se charge de faire un FreeLibrary et
de s'enlever lui-meme de la liste :)
Et Module::Free() est statique donc l'objet qu'on delete ne
peut pas etre le contexte dans lequel est apelle cette
fonction membre puisqu'il y n'y a pas de "this" :)
<code>
Module::~Module()
{
cout << this << " Module::~Module()" << endl;
cout << name << ": freeing..." << endl;
if (hProcFree)
hProcFree();
FreeLibrary(hinstLib);
linked.remove(this);
}
</code>
Si tu parles de l'invalidite d'un autre pointeur explicite
plus stp :)
D'accord, mais c'est subtile. Et c'est probable que std::list<>
ne soit pas la structure qu'il te faut -- comment faire un
erase() de l'objet dans la liste sans en avoir l'itérateur ? (Ou
est-ce que le constructeur fait l'insértion (avec insert, et non
avec push_back) et sauve l'itérateur.
Pour ce genre d'application, il me semble que std::set est tout
indiqué. (J'imagine qu'en fait, tu n'aurais jamais plusieurs
Module avec le même nom. Sinon, il y a aussi std::multi_set.)
[...]
N'empèche que je verrais plutôt un std::set ou un std::map. Je
ne crois pas que ce soit un problème ici (parce que la liste ne
contiendra jamais des milliers d'entrées), mais list<>::remove()
a une compléxité O(n), où n est le nombre d'éntrées dans la
liste. Ce qui fait que ta fonction Free est quadratique.
D'accord, mais c'est subtile. Et c'est probable que std::list<>
ne soit pas la structure qu'il te faut -- comment faire un
erase() de l'objet dans la liste sans en avoir l'itérateur ? (Ou
est-ce que le constructeur fait l'insértion (avec insert, et non
avec push_back) et sauve l'itérateur.
Pour ce genre d'application, il me semble que std::set est tout
indiqué. (J'imagine qu'en fait, tu n'aurais jamais plusieurs
Module avec le même nom. Sinon, il y a aussi std::multi_set.)
[...]
N'empèche que je verrais plutôt un std::set ou un std::map. Je
ne crois pas que ce soit un problème ici (parce que la liste ne
contiendra jamais des milliers d'entrées), mais list<>::remove()
a une compléxité O(n), où n est le nombre d'éntrées dans la
liste. Ce qui fait que ta fonction Free est quadratique.
D'accord, mais c'est subtile. Et c'est probable que std::list<>
ne soit pas la structure qu'il te faut -- comment faire un
erase() de l'objet dans la liste sans en avoir l'itérateur ? (Ou
est-ce que le constructeur fait l'insértion (avec insert, et non
avec push_back) et sauve l'itérateur.
Pour ce genre d'application, il me semble que std::set est tout
indiqué. (J'imagine qu'en fait, tu n'aurais jamais plusieurs
Module avec le même nom. Sinon, il y a aussi std::multi_set.)
[...]
N'empèche que je verrais plutôt un std::set ou un std::map. Je
ne crois pas que ce soit un problème ici (parce que la liste ne
contiendra jamais des milliers d'entrées), mais list<>::remove()
a une compléxité O(n), où n est le nombre d'éntrées dans la
liste. Ce qui fait que ta fonction Free est quadratique.
list <Module *>::iterator it;
list <Module *>::iterator save;
it = Module::linked.begin();
Pourquoi séparer l'initialisation de la déclaration ? Et
pourquoi déclarer la variable save ici, et non dans la boucle ?
C'etait hier ma premiere utilisation des iterator, et j'etais
deja content que ca marche, j'ai pas encore les bons reflexes.
list <Module *>::iterator it;
list <Module *>::iterator save;
it = Module::linked.begin();
Pourquoi séparer l'initialisation de la déclaration ? Et
pourquoi déclarer la variable save ici, et non dans la boucle ?
C'etait hier ma premiere utilisation des iterator, et j'etais
deja content que ca marche, j'ai pas encore les bons reflexes.
list <Module *>::iterator it;
list <Module *>::iterator save;
it = Module::linked.begin();
Pourquoi séparer l'initialisation de la déclaration ? Et
pourquoi déclarer la variable save ici, et non dans la boucle ?
C'etait hier ma premiere utilisation des iterator, et j'etais
deja content que ca marche, j'ai pas encore les bons reflexes.
"kanze" writes:D'accord, mais c'est subtile. Et c'est probable que
std::list<> ne soit pas la structure qu'il te faut --
comment faire un erase() de l'objet dans la liste sans en
avoir l'itérateur ? (Ou est-ce que le constructeur fait
l'insértion (avec insert, et non avec push_back) et sauve
l'itérateur.
La liste est statique publique donc on peut toujours avoir un
iterateur sur elle, ou la parcourir avec un for et delete les
objets
Le constructeur fait effectivement l'insertion, mais avec
push_back: new Module((basic_string <char>)"mod_test.dll");
Quelle est la difference de vitesse entre push_back et insert?
J'ose esperer que la class maintient un pointeur vers le
dernier et premier element vu que ces operations sont a priori
courantes. J'ose supposer que la liste est doublement chainee
vu qu'il y'a des iterators bidirectionnel
Pour ce genre d'application, il me semble que std::set est
tout indiqué. (J'imagine qu'en fait, tu n'aurais jamais
plusieurs Module avec le même nom. Sinon, il y a aussi
std::multi_set.)
[...]
N'empèche que je verrais plutôt un std::set ou un std::map.
Je ne crois pas que ce soit un problème ici (parce que la
liste ne contiendra jamais des milliers d'entrées), mais
list<>::remove() a une compléxité O(n), où n est le nombre
d'éntrées dans la liste. Ce qui fait que ta fonction Free
est quadratique.
Globalement les insert/remove se font qu'au lancement et a la
fin du serveur et y'aura en effet peu d'entree. Mais j'ai
besoin que ca soit une liste non triee (bien que l'on puisse
apparament specifier la fonction de tri pour std::set et donc
simuler un tri qui ne trie pas). Le projet est en fait un
apache-like, sans bien sur en avoir la pretention (projet
d'etudiant), et il est important de conserver l'ordre des
modules comme dans apache, car des hooks sont contenus a
l'interieur desdits modules et certains doivent agir avant ou
apres d'autres (ils sont appeles dans l'ordre de la liste).
En fait le plus important c'est qu'au final la liste soit
parcourue en lecture seule le plus rapidement possible, et la
je ne sais pas quel est la classe la plus adaptee ?
"kanze" <kanze@gabi-soft.fr> writes:
D'accord, mais c'est subtile. Et c'est probable que
std::list<> ne soit pas la structure qu'il te faut --
comment faire un erase() de l'objet dans la liste sans en
avoir l'itérateur ? (Ou est-ce que le constructeur fait
l'insértion (avec insert, et non avec push_back) et sauve
l'itérateur.
La liste est statique publique donc on peut toujours avoir un
iterateur sur elle, ou la parcourir avec un for et delete les
objets
Le constructeur fait effectivement l'insertion, mais avec
push_back: new Module((basic_string <char>)"mod_test.dll");
Quelle est la difference de vitesse entre push_back et insert?
J'ose esperer que la class maintient un pointeur vers le
dernier et premier element vu que ces operations sont a priori
courantes. J'ose supposer que la liste est doublement chainee
vu qu'il y'a des iterators bidirectionnel
Pour ce genre d'application, il me semble que std::set est
tout indiqué. (J'imagine qu'en fait, tu n'aurais jamais
plusieurs Module avec le même nom. Sinon, il y a aussi
std::multi_set.)
[...]
N'empèche que je verrais plutôt un std::set ou un std::map.
Je ne crois pas que ce soit un problème ici (parce que la
liste ne contiendra jamais des milliers d'entrées), mais
list<>::remove() a une compléxité O(n), où n est le nombre
d'éntrées dans la liste. Ce qui fait que ta fonction Free
est quadratique.
Globalement les insert/remove se font qu'au lancement et a la
fin du serveur et y'aura en effet peu d'entree. Mais j'ai
besoin que ca soit une liste non triee (bien que l'on puisse
apparament specifier la fonction de tri pour std::set et donc
simuler un tri qui ne trie pas). Le projet est en fait un
apache-like, sans bien sur en avoir la pretention (projet
d'etudiant), et il est important de conserver l'ordre des
modules comme dans apache, car des hooks sont contenus a
l'interieur desdits modules et certains doivent agir avant ou
apres d'autres (ils sont appeles dans l'ordre de la liste).
En fait le plus important c'est qu'au final la liste soit
parcourue en lecture seule le plus rapidement possible, et la
je ne sais pas quel est la classe la plus adaptee ?
"kanze" writes:D'accord, mais c'est subtile. Et c'est probable que
std::list<> ne soit pas la structure qu'il te faut --
comment faire un erase() de l'objet dans la liste sans en
avoir l'itérateur ? (Ou est-ce que le constructeur fait
l'insértion (avec insert, et non avec push_back) et sauve
l'itérateur.
La liste est statique publique donc on peut toujours avoir un
iterateur sur elle, ou la parcourir avec un for et delete les
objets
Le constructeur fait effectivement l'insertion, mais avec
push_back: new Module((basic_string <char>)"mod_test.dll");
Quelle est la difference de vitesse entre push_back et insert?
J'ose esperer que la class maintient un pointeur vers le
dernier et premier element vu que ces operations sont a priori
courantes. J'ose supposer que la liste est doublement chainee
vu qu'il y'a des iterators bidirectionnel
Pour ce genre d'application, il me semble que std::set est
tout indiqué. (J'imagine qu'en fait, tu n'aurais jamais
plusieurs Module avec le même nom. Sinon, il y a aussi
std::multi_set.)
[...]
N'empèche que je verrais plutôt un std::set ou un std::map.
Je ne crois pas que ce soit un problème ici (parce que la
liste ne contiendra jamais des milliers d'entrées), mais
list<>::remove() a une compléxité O(n), où n est le nombre
d'éntrées dans la liste. Ce qui fait que ta fonction Free
est quadratique.
Globalement les insert/remove se font qu'au lancement et a la
fin du serveur et y'aura en effet peu d'entree. Mais j'ai
besoin que ca soit une liste non triee (bien que l'on puisse
apparament specifier la fonction de tri pour std::set et donc
simuler un tri qui ne trie pas). Le projet est en fait un
apache-like, sans bien sur en avoir la pretention (projet
d'etudiant), et il est important de conserver l'ordre des
modules comme dans apache, car des hooks sont contenus a
l'interieur desdits modules et certains doivent agir avant ou
apres d'autres (ils sont appeles dans l'ordre de la liste).
En fait le plus important c'est qu'au final la liste soit
parcourue en lecture seule le plus rapidement possible, et la
je ne sais pas quel est la classe la plus adaptee ?