map : suppression via un itérateur et incrémentation de l'itérateur
11 réponses
MGN
bonjour,
une question bête, mais je veux être sûr de ne pas me tromper :-)
_values est un objet map
code :
it=std::find_if(_values.begin(),_values.end(),upper_keys);
while(it!=_values.end())
{
_values.erase(it);
it=std::find_if(it,_values.end(),upper_keys);
// <- ma question est ici
// it=std::find_if(++it,_values.end(),upper_keys);
<- version fausse
}
je supprime l'objet pointé donc il ne faut pas incrémenter
l'itérateur...C'est bien ça ?
Il n'y a pas de risque avec cette écriture ? par exemple si it pointait vers
le dernier élément du conteneur ?
Merci pour vos lumières
Marc
une question bête, mais je veux être sûr de ne pas me tromper :-)
_values est un objet map
C-à-d de type std::map<X,Y>, je suppose.
code : it=std::find_if(_values.begin(),_values.end(),upper_k eys); while(it!=_values.end()) { _values.erase(it); it=std::find_if(it,_values.end(),upper_keys); // <- ma question est ici // it=std::find_if(++it,_values.end(),upper_keys); <- version fausse
Les deux sont faux. Après l'erase, it n'est plus valid. Tu ne peux rien faire avec lui. Strictement parlant, même pas le copier, mais en aucun cas le passer comme paramètre à un algorithme ou à une fonction membre. Il y a deux possibilités :
_values.erase( it ++ ) ; it = std::find_if( it, _values.end(), upper_keys ) ;
On incrémente la copie locale avant de faire l'erase. Ou (celui que je préfère) :
it = std::find_if( _values.erase( it ), _values.end(), upper_keys ) ;
tout simplement. Les fonctions erase renvoie normalement l'itérateur de l'élément qui suivait l'élément qu'ils ont supprimé.
}
je supprime l'objet pointé donc il ne faut pas incrémenter l'itérateur...C'est bien ça ?
Ni l'incrémenter, ni le passer comme paramètre à une fonction.
Il n'y a pas de risque avec cette écriture ? par exemple si it pointait vers le dernier élément du conteneur ?
Après l'incrémentation, ou la valeur de rétour de erase(), peut bien désigner la fin du map. Mais ça ne doit pas poser de problème : on a droit de passer une suite vide à un algorithme de la bibliothèque standard. (L'implémentation typique de find_if serait quelque chose du genre :
while ( begin != end && ! predicate( *begin ) ) { ++ begin ; } return begin ;
Si les deux itérateurs sont égaux, on n'entre pas dans la boucle.)
-- 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
MGN wrote:
une question bête, mais je veux être sûr de ne pas me tromper :-)
_values est un objet map
C-à-d de type std::map<X,Y>, je suppose.
code :
it=std::find_if(_values.begin(),_values.end(),upper_k eys);
while(it!=_values.end())
{
_values.erase(it);
it=std::find_if(it,_values.end(),upper_keys);
// <- ma question est ici
// it=std::find_if(++it,_values.end(),upper_keys);
<- version fausse
Les deux sont faux. Après l'erase, it n'est plus valid. Tu ne
peux rien faire avec lui. Strictement parlant, même pas le
copier, mais en aucun cas le passer comme paramètre à un
algorithme ou à une fonction membre. Il y a deux possibilités :
_values.erase( it ++ ) ;
it = std::find_if( it, _values.end(), upper_keys ) ;
On incrémente la copie locale avant de faire l'erase. Ou (celui
que je préfère) :
it = std::find_if( _values.erase( it ), _values.end(), upper_keys )
;
tout simplement. Les fonctions erase renvoie normalement
l'itérateur de l'élément qui suivait l'élément qu'ils ont
supprimé.
}
je supprime l'objet pointé donc il ne faut pas incrémenter
l'itérateur...C'est bien ça ?
Ni l'incrémenter, ni le passer comme paramètre à une fonction.
Il n'y a pas de risque avec cette écriture ? par exemple si it
pointait vers le dernier élément du conteneur ?
Après l'incrémentation, ou la valeur de rétour de erase(), peut
bien désigner la fin du map. Mais ça ne doit pas poser de
problème : on a droit de passer une suite vide à un algorithme
de la bibliothèque standard. (L'implémentation typique de
find_if serait quelque chose du genre :
while ( begin != end && ! predicate( *begin ) ) {
++ begin ;
}
return begin ;
Si les deux itérateurs sont égaux, on n'entre pas dans la
boucle.)
--
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
une question bête, mais je veux être sûr de ne pas me tromper :-)
_values est un objet map
C-à-d de type std::map<X,Y>, je suppose.
code : it=std::find_if(_values.begin(),_values.end(),upper_k eys); while(it!=_values.end()) { _values.erase(it); it=std::find_if(it,_values.end(),upper_keys); // <- ma question est ici // it=std::find_if(++it,_values.end(),upper_keys); <- version fausse
Les deux sont faux. Après l'erase, it n'est plus valid. Tu ne peux rien faire avec lui. Strictement parlant, même pas le copier, mais en aucun cas le passer comme paramètre à un algorithme ou à une fonction membre. Il y a deux possibilités :
_values.erase( it ++ ) ; it = std::find_if( it, _values.end(), upper_keys ) ;
On incrémente la copie locale avant de faire l'erase. Ou (celui que je préfère) :
it = std::find_if( _values.erase( it ), _values.end(), upper_keys ) ;
tout simplement. Les fonctions erase renvoie normalement l'itérateur de l'élément qui suivait l'élément qu'ils ont supprimé.
}
je supprime l'objet pointé donc il ne faut pas incrémenter l'itérateur...C'est bien ça ?
Ni l'incrémenter, ni le passer comme paramètre à une fonction.
Il n'y a pas de risque avec cette écriture ? par exemple si it pointait vers le dernier élément du conteneur ?
Après l'incrémentation, ou la valeur de rétour de erase(), peut bien désigner la fin du map. Mais ça ne doit pas poser de problème : on a droit de passer une suite vide à un algorithme de la bibliothèque standard. (L'implémentation typique de find_if serait quelque chose du genre :
while ( begin != end && ! predicate( *begin ) ) { ++ begin ; } return begin ;
Si les deux itérateurs sont égaux, on n'entre pas dans la boucle.)
-- 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
MGN
je te remercie BEAUCOUP ! Le pire, c'est que j'ai fait un logiciel qui marche très bien depuis 4 ans (utilisé quotidiennement par environ 100 personnes...) et dans lequel je fait des erase(it) sur des vector ! Bon, je vais rechercher partout mes erase dans mes programmes pour corriger ! Merci encore Marc
je te remercie BEAUCOUP !
Le pire, c'est que j'ai fait un logiciel qui marche très bien depuis 4 ans
(utilisé quotidiennement par environ 100 personnes...) et dans lequel je
fait des erase(it) sur des vector !
Bon, je vais rechercher partout mes erase dans mes programmes pour corriger
!
Merci encore
Marc
je te remercie BEAUCOUP ! Le pire, c'est que j'ai fait un logiciel qui marche très bien depuis 4 ans (utilisé quotidiennement par environ 100 personnes...) et dans lequel je fait des erase(it) sur des vector ! Bon, je vais rechercher partout mes erase dans mes programmes pour corriger ! Merci encore Marc
MGN
Malheur, dans ma version de la STL (j'utilise BC6), erase ne retourne pas d'iterateur. Extrait de la doc :
void erase(iterator position); Deletes the map element pointed to by the iterator position. Returns an iterator pointing to the element following the deleted element, or end() if the deleted item was the last one in this list.
Le moins qu'on puisse dire, c'est qu'il y a contradiction entre le texte et le prototype de la fonction ! Mais si j'essaye, j'ai bien un message d'erreur !
Je me pose une question. Quand tu écris
_values.erase( it ++ ) ; it = std::find_if( it, _values.end(), upper_keys ) ;
ça marche parce qu'il n'y a pas de réallocation de mémoire pour les éléments du conteneur map après un erase, alors que dans un vecteur, tous les éléments du vecteurs sont décalés après un erase (d'où l'inefficacité d'un suppression en milieu de vecteur).
En conclusion, pour un vecteur, après vecteur.erase(it); it pointe vers l'élément suivant immédiatement l'élément supprimé, sans qu'il faille l'incrémenter (par it++ par exemple) C'est ça ? Marc
Malheur, dans ma version de la STL (j'utilise BC6), erase ne retourne pas
d'iterateur.
Extrait de la doc :
void erase(iterator position);
Deletes the map element pointed to by the iterator position. Returns an
iterator pointing to the element following the deleted element, or end() if
the deleted item was the last one in this list.
Le moins qu'on puisse dire, c'est qu'il y a contradiction entre le texte et
le prototype de la fonction !
Mais si j'essaye, j'ai bien un message d'erreur !
Je me pose une question. Quand tu écris
_values.erase( it ++ ) ;
it = std::find_if( it, _values.end(), upper_keys ) ;
ça marche parce qu'il n'y a pas de réallocation de mémoire pour les éléments
du conteneur map après un erase, alors que dans un vecteur, tous les
éléments du vecteurs sont décalés après un erase (d'où l'inefficacité d'un
suppression en milieu de vecteur).
En conclusion, pour un vecteur, après
vecteur.erase(it);
it pointe vers l'élément suivant immédiatement l'élément supprimé, sans
qu'il faille l'incrémenter (par it++ par exemple)
C'est ça ?
Marc
Malheur, dans ma version de la STL (j'utilise BC6), erase ne retourne pas d'iterateur. Extrait de la doc :
void erase(iterator position); Deletes the map element pointed to by the iterator position. Returns an iterator pointing to the element following the deleted element, or end() if the deleted item was the last one in this list.
Le moins qu'on puisse dire, c'est qu'il y a contradiction entre le texte et le prototype de la fonction ! Mais si j'essaye, j'ai bien un message d'erreur !
Je me pose une question. Quand tu écris
_values.erase( it ++ ) ; it = std::find_if( it, _values.end(), upper_keys ) ;
ça marche parce qu'il n'y a pas de réallocation de mémoire pour les éléments du conteneur map après un erase, alors que dans un vecteur, tous les éléments du vecteurs sont décalés après un erase (d'où l'inefficacité d'un suppression en milieu de vecteur).
En conclusion, pour un vecteur, après vecteur.erase(it); it pointe vers l'élément suivant immédiatement l'élément supprimé, sans qu'il faille l'incrémenter (par it++ par exemple) C'est ça ? Marc
kanze
MGN wrote:
Le pire, c'est que j'ai fait un logiciel qui marche très bien depuis 4 ans (utilisé quotidiennement par environ 100 personnes...) et dans lequel je fait des erase(it) sur des vector !
Formellement, c'est un comportement indéfini, mais dans la pratique, l'itérateur désignera l'élément suivant, s'il existe, et sinon end(). Pour std::vector ; non pour les autres collections.
-- 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
MGN wrote:
Le pire, c'est que j'ai fait un logiciel qui marche très bien
depuis 4 ans (utilisé quotidiennement par environ 100
personnes...) et dans lequel je fait des erase(it) sur des
vector !
Formellement, c'est un comportement indéfini, mais dans la
pratique, l'itérateur désignera l'élément suivant, s'il existe,
et sinon end(). Pour std::vector ; non pour les autres
collections.
--
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
Le pire, c'est que j'ai fait un logiciel qui marche très bien depuis 4 ans (utilisé quotidiennement par environ 100 personnes...) et dans lequel je fait des erase(it) sur des vector !
Formellement, c'est un comportement indéfini, mais dans la pratique, l'itérateur désignera l'élément suivant, s'il existe, et sinon end(). Pour std::vector ; non pour les autres collections.
-- 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
kanze
MGN wrote:
Malheur, dans ma version de la STL (j'utilise BC6), erase ne retourne pas d'iterateur.
Extrait de la doc :
void erase(iterator position);
Deletes the map element pointed to by the iterator position. Returns an iterator pointing to the element following the deleted element, or end() if the deleted item was the last one in this list.
Intéressant. Signature « void... », puis « Returns... » dans la description. Il faudrait essayer, pour voir lequel est juste. (Et j'espère pour toi que la qualité de l'implémentation est mieux que la qualité de la documentation.)
Le moins qu'on puisse dire, c'est qu'il y a contradiction entre le texte et le prototype de la fonction !
Mais si j'essaye, j'ai bien un message d'erreur !
Ce que je conseille, c'est un autre compilateur, ou au moins une autre version de la bibliothèque. VC++ est maintenant disponible gratuitement, et g++ l'est depuis toujours. À mon avis, un téléchargement de Visual Studios 2005 ou de MinWG s'impose.
Je me pose une question. Quand tu écris
_values.erase( it ++ ) ; it = std::find_if( it, _values.end(), upper_keys ) ;
ça marche parce qu'il n'y a pas de réallocation de mémoire pour les éléments du conteneur map après un erase, alors que dans un vecteur, tous les éléments du vecteurs sont décalés après un erase (d'où l'inefficacité d'un suppression en milieu de vecteur).
Ça marche parce que la norme dit qu'erase n'invalide que les itérateurs qui désignent un objet effacé pour liste, mais qu'elle invalide tous les itérateurs sur des éléments qui suit sur un vecteur. (Mais la raison pour cette différence, c'est effectivement ce que tu dis.)
En conclusion, pour un vecteur, après vecteur.erase(it); it pointe vers l'élément suivant immédiatement l'élément supprimé, sans qu'il faille l'incrémenter (par it++ par exemple)
C'est ça ?
Non. Pour un vector, tout itérateur vers l'élément supprimé OU vers un élément qui lui suivait dans la suite devient invalid. Ce que tu décris est vrai dans des implémentations typiques simplistes, mais ce n'est pas garanti, et des versions recentes de g++ (et de VC++ aussi, je crois, mais je ne l'ai pas essayé) font en sorte qu'il y a un échec d'une assertion si tu essaies de t'en servir.
La façon prévue par la norme de résoudre ce problème, c'est d'utiliser la valeur de rétour de erase() ; c'est pour ça qu'elle est là. (Elle manquait dans les collections associatives dans la première version de la norme, mais ça a été corrigé depuis.) Sinon, il faut une solution différente par type de collection : avec vector et deque, grosso modo, il faut prendre l'indice (iter - begin()), puis réconstituer l'itérateur après la suppression (begin() + indice) ; si tu sais que ce n'est pas le premier élément, tu pourrais aussi garder une copie de itérateur moins 1, et incrémenter ça par la suite. Pour list, la solution que j'ai indiqué marche. Pour les collections associatives (et il y a bien plus de chances pour que erase renvoie void dans ces cas-là, parce que la renvoie de l'itérateur est une correction plus récente), la seule solution qui me vient à l'esprit, c'est de sauvegarde la clé avant, puis utiliser upper_bound pour se répositionner après la suppression.
-- 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
MGN wrote:
Malheur, dans ma version de la STL (j'utilise BC6), erase ne
retourne pas d'iterateur.
Extrait de la doc :
void erase(iterator position);
Deletes the map element pointed to by the iterator position.
Returns an iterator pointing to the element following the
deleted element, or end() if the deleted item was the last one
in this list.
Intéressant. Signature « void... », puis « Returns... »
dans la description. Il faudrait essayer, pour voir lequel est
juste. (Et j'espère pour toi que la qualité de l'implémentation
est mieux que la qualité de la documentation.)
Le moins qu'on puisse dire, c'est qu'il y a contradiction
entre le texte et le prototype de la fonction !
Mais si j'essaye, j'ai bien un message d'erreur !
Ce que je conseille, c'est un autre compilateur, ou au moins une
autre version de la bibliothèque. VC++ est maintenant disponible
gratuitement, et g++ l'est depuis toujours. À mon avis, un
téléchargement de Visual Studios 2005 ou de MinWG s'impose.
Je me pose une question. Quand tu écris
_values.erase( it ++ ) ;
it = std::find_if( it, _values.end(), upper_keys ) ;
ça marche parce qu'il n'y a pas de réallocation de mémoire
pour les éléments du conteneur map après un erase, alors que
dans un vecteur, tous les éléments du vecteurs sont décalés
après un erase (d'où l'inefficacité d'un suppression en milieu
de vecteur).
Ça marche parce que la norme dit qu'erase n'invalide que les
itérateurs qui désignent un objet effacé pour liste, mais
qu'elle invalide tous les itérateurs sur des éléments qui suit
sur un vecteur. (Mais la raison pour cette différence, c'est
effectivement ce que tu dis.)
En conclusion, pour un vecteur, après
vecteur.erase(it);
it pointe vers l'élément suivant immédiatement l'élément
supprimé, sans qu'il faille l'incrémenter (par it++ par
exemple)
C'est ça ?
Non. Pour un vector, tout itérateur vers l'élément supprimé OU
vers un élément qui lui suivait dans la suite devient invalid.
Ce que tu décris est vrai dans des implémentations typiques
simplistes, mais ce n'est pas garanti, et des versions recentes
de g++ (et de VC++ aussi, je crois, mais je ne l'ai pas essayé)
font en sorte qu'il y a un échec d'une assertion si tu essaies
de t'en servir.
La façon prévue par la norme de résoudre ce problème, c'est
d'utiliser la valeur de rétour de erase() ; c'est pour ça
qu'elle est là. (Elle manquait dans les collections associatives
dans la première version de la norme, mais ça a été corrigé
depuis.) Sinon, il faut une solution différente par type de
collection : avec vector et deque, grosso modo, il faut prendre
l'indice (iter - begin()), puis réconstituer l'itérateur après
la suppression (begin() + indice) ; si tu sais que ce n'est pas
le premier élément, tu pourrais aussi garder une copie de
itérateur moins 1, et incrémenter ça par la suite. Pour list, la
solution que j'ai indiqué marche. Pour les collections
associatives (et il y a bien plus de chances pour que erase
renvoie void dans ces cas-là, parce que la renvoie de
l'itérateur est une correction plus récente), la seule solution
qui me vient à l'esprit, c'est de sauvegarde la clé avant, puis
utiliser upper_bound pour se répositionner après la suppression.
--
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
Malheur, dans ma version de la STL (j'utilise BC6), erase ne retourne pas d'iterateur.
Extrait de la doc :
void erase(iterator position);
Deletes the map element pointed to by the iterator position. Returns an iterator pointing to the element following the deleted element, or end() if the deleted item was the last one in this list.
Intéressant. Signature « void... », puis « Returns... » dans la description. Il faudrait essayer, pour voir lequel est juste. (Et j'espère pour toi que la qualité de l'implémentation est mieux que la qualité de la documentation.)
Le moins qu'on puisse dire, c'est qu'il y a contradiction entre le texte et le prototype de la fonction !
Mais si j'essaye, j'ai bien un message d'erreur !
Ce que je conseille, c'est un autre compilateur, ou au moins une autre version de la bibliothèque. VC++ est maintenant disponible gratuitement, et g++ l'est depuis toujours. À mon avis, un téléchargement de Visual Studios 2005 ou de MinWG s'impose.
Je me pose une question. Quand tu écris
_values.erase( it ++ ) ; it = std::find_if( it, _values.end(), upper_keys ) ;
ça marche parce qu'il n'y a pas de réallocation de mémoire pour les éléments du conteneur map après un erase, alors que dans un vecteur, tous les éléments du vecteurs sont décalés après un erase (d'où l'inefficacité d'un suppression en milieu de vecteur).
Ça marche parce que la norme dit qu'erase n'invalide que les itérateurs qui désignent un objet effacé pour liste, mais qu'elle invalide tous les itérateurs sur des éléments qui suit sur un vecteur. (Mais la raison pour cette différence, c'est effectivement ce que tu dis.)
En conclusion, pour un vecteur, après vecteur.erase(it); it pointe vers l'élément suivant immédiatement l'élément supprimé, sans qu'il faille l'incrémenter (par it++ par exemple)
C'est ça ?
Non. Pour un vector, tout itérateur vers l'élément supprimé OU vers un élément qui lui suivait dans la suite devient invalid. Ce que tu décris est vrai dans des implémentations typiques simplistes, mais ce n'est pas garanti, et des versions recentes de g++ (et de VC++ aussi, je crois, mais je ne l'ai pas essayé) font en sorte qu'il y a un échec d'une assertion si tu essaies de t'en servir.
La façon prévue par la norme de résoudre ce problème, c'est d'utiliser la valeur de rétour de erase() ; c'est pour ça qu'elle est là. (Elle manquait dans les collections associatives dans la première version de la norme, mais ça a été corrigé depuis.) Sinon, il faut une solution différente par type de collection : avec vector et deque, grosso modo, il faut prendre l'indice (iter - begin()), puis réconstituer l'itérateur après la suppression (begin() + indice) ; si tu sais que ce n'est pas le premier élément, tu pourrais aussi garder une copie de itérateur moins 1, et incrémenter ça par la suite. Pour list, la solution que j'ai indiqué marche. Pour les collections associatives (et il y a bien plus de chances pour que erase renvoie void dans ces cas-là, parce que la renvoie de l'itérateur est une correction plus récente), la seule solution qui me vient à l'esprit, c'est de sauvegarde la clé avant, puis utiliser upper_bound pour se répositionner après la suppression.
-- 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
MGN
merci c'est pénible ces différentes versions de la STL. Et bien sûr, pas question d'y toucher...
merci
c'est pénible ces différentes versions de la STL.
Et bien sûr, pas question d'y toucher...
merci c'est pénible ces différentes versions de la STL. Et bien sûr, pas question d'y toucher...
MGN
j'ai pas bien compris la dernière partie de ta réponse sur les collections associatives... Quand j'écris pour un conteneur map _values.erase(it++); it=std::find_if(it,_values.end(),upper_keys); ça ne marche pas ? Nota : j'ai regardé le fichier map.h de mon implémentation de la STL et j'ai bien void erase(iterator position); Hélas... Marc
j'ai pas bien compris la dernière partie de ta réponse sur les collections
associatives...
Quand j'écris pour un conteneur map
_values.erase(it++);
it=std::find_if(it,_values.end(),upper_keys);
ça ne marche pas ?
Nota : j'ai regardé le fichier map.h de mon implémentation de la STL et j'ai
bien
void erase(iterator position);
Hélas...
Marc
j'ai pas bien compris la dernière partie de ta réponse sur les collections associatives... Quand j'écris pour un conteneur map _values.erase(it++); it=std::find_if(it,_values.end(),upper_keys); ça ne marche pas ? Nota : j'ai regardé le fichier map.h de mon implémentation de la STL et j'ai bien void erase(iterator position); Hélas... Marc
kanze
MGN wrote:
j'ai pas bien compris la dernière partie de ta réponse sur les collec tions associatives... Quand j'écris pour un conteneur map _values.erase(it++); it=std::find_if(it,_values.end(),upper_keys); ça ne marche pas ?
Tout à fait. Je pensais en fait à la fonction erase qui prend des clés ; elle peut bien en effacer plus d'un élément (pas dans map, mais en général).
-- 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
MGN wrote:
j'ai pas bien compris la dernière partie de ta réponse sur les collec tions
associatives...
Quand j'écris pour un conteneur map
_values.erase(it++);
it=std::find_if(it,_values.end(),upper_keys);
ça ne marche pas ?
Tout à fait. Je pensais en fait à la fonction erase qui prend
des clés ; elle peut bien en effacer plus d'un élément (pas
dans map, mais en général).
--
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
j'ai pas bien compris la dernière partie de ta réponse sur les collec tions associatives... Quand j'écris pour un conteneur map _values.erase(it++); it=std::find_if(it,_values.end(),upper_keys); ça ne marche pas ?
Tout à fait. Je pensais en fait à la fonction erase qui prend des clés ; elle peut bien en effacer plus d'un élément (pas dans map, mais en général).
-- 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
Fabien LE LEZ
On Thu, 12 Oct 2006 09:28:06 +0200, "MGN" :
c'est pénible ces différentes versions de la STL.
Différents bugs dans les implémentations, tu veux dire ?
Et bien sûr, pas question d'y toucher...
On peut changer l'implémentation de la STL, soit en changeant tout le système (par exemple en utilisant VC++ 2005 à la place d'un vieux compilo), soit en changeant juste la STL (par exemple, en mettant celle de SGI à la place de celle fournie avec le compilo).
On Thu, 12 Oct 2006 09:28:06 +0200, "MGN" <mgueguen@metrica.fr>:
c'est pénible ces différentes versions de la STL.
Différents bugs dans les implémentations, tu veux dire ?
Et bien sûr, pas question d'y toucher...
On peut changer l'implémentation de la STL, soit en changeant tout le
système (par exemple en utilisant VC++ 2005 à la place d'un vieux
compilo), soit en changeant juste la STL (par exemple, en mettant
celle de SGI à la place de celle fournie avec le compilo).
Différents bugs dans les implémentations, tu veux dire ?
Et bien sûr, pas question d'y toucher...
On peut changer l'implémentation de la STL, soit en changeant tout le système (par exemple en utilisant VC++ 2005 à la place d'un vieux compilo), soit en changeant juste la STL (par exemple, en mettant celle de SGI à la place de celle fournie avec le compilo).
Marc G
compilo), soit en changeant juste la STL (par exemple, en mettant celle de SGI à la place de celle fournie avec le compilo). j'ai l'impression que ça se fait pas comme ça avec mon compilo (C++ Builder
6). J'ai des constantes symboliques définies un peu partout et propres à mon implémentation. Et puis si des classes de la VCL utilisent (ce qui me semble très probable) la STL. Si je change d'implémentation, je risque la catastrophe. Non ? Marc
compilo), soit en changeant juste la STL (par exemple, en mettant
celle de SGI à la place de celle fournie avec le compilo).
j'ai l'impression que ça se fait pas comme ça avec mon compilo (C++ Builder
6). J'ai des constantes symboliques définies un peu partout et propres à mon
implémentation. Et puis si des classes de la VCL utilisent (ce qui me semble
très probable) la STL. Si je change d'implémentation, je risque la
catastrophe. Non ?
Marc
compilo), soit en changeant juste la STL (par exemple, en mettant celle de SGI à la place de celle fournie avec le compilo). j'ai l'impression que ça se fait pas comme ça avec mon compilo (C++ Builder
6). J'ai des constantes symboliques définies un peu partout et propres à mon implémentation. Et puis si des classes de la VCL utilisent (ce qui me semble très probable) la STL. Si je change d'implémentation, je risque la catastrophe. Non ? Marc