J'essaie tant bien que mal d'utiliser la librarie STL, et particulièrement
la classe "list".
Ma question est donc la suivante, ai-je le droit de faire ça, sans que mon
programme plante ?
Voici un listing "simplifié":
dans un liste : list<char *> test; je met divers mots avec
test.push_front();
Ensuite je parcous cette liste.
list<char *>::iterator i;
for (i=test.begin(); i!=test.end(); i++)
{
if (strcmp(*i,"effacer")==0)
test.erase(i);
}
Le programme plante. Je me doute bien qu'il y a problème d'index. Mais même
si je fais le test:
Quelle est la différence entre Std et Stl au niveau fonctionnel ?
gg
gg
"kanze" a écrit dans le message de news:
Arnaud Debaene wrote:
"gg" a écrit dans le message de news: 452cd988$0$27395$
Ceci m'amène à un autre problème que je trouve plutôt délicat. Comment inverser deux éléments connus d'une liste en un minimum de temps ? Exemple, j'ai une liste (de pointeurs pour être exact), et je désirerai inverser deux éléments de cette liste (et ne pas inverser le contenu des pointeurs), d'autre part, dans le programme, d'autres variables utilisent ces éléments.
Ça marche si ce qu'il a voulu dire, c'est de ne pas invalider des pointeurs à des objets dont les pointeurs se trouvent dans la liste. Sa mention de pointeurs rend la question un peu vague, mais si on a des pointeurs à des éléments de la liste (quelque soit le type d'élément -- des pointeurs à des pointeurs, donc, si la liste contient des pointeurs), et qu'on veut qu'ils pointent toujours au même objet, il faut faire quelque chose du genre :
//! pre //! pos1 et pos2 sont des itérateurs dans l. //! pos1 != pos2. // --------------------------------------------------------------- template< typename T > void lswap( std::list< T >& l, typename std::list< T >::iterator pos1, typename std::list< T >::iterator pos2 ) { std::list< T > a ; a.splice( a.begin(), l, pos1 ++ ) ; std::list< T > b ; b.splice( b.begin(), l, pos2 ++ ) ; l.splice( pos1, b ) ; l.splice( pos2, a ) ; }
À la suite, les éléments à pos1 et à pos2 sont échangés, et tout itérateur, pointeur ou référence qui désignait l'élément à pos1 le désigne encore, à sa nouvelle position, de même pour pos2. (En fait, je suis sûr qu'on pourrait le faire avec une seule liste temporaire, voire aucune :
mais je me sens pas sûr en ce qui concerne les cas limites, par exemple quand pos1 et pos2 sont adjacents, et je trouve la version avec deux temporaires bien plus simple à comprendre.)
------
Et lorsque qu'on ne connait pas à l'avance la position d'un élément ? Comment fait-on pour la connaître ? Inévitablement, il va falloir parcourir la liste ... non ?
gg
"kanze" <kanze@gabi-soft.fr> a écrit dans le message de news:
1160640357.639902.249270@b28g2000cwb.googlegroups.com...
Arnaud Debaene wrote:
"gg" <gg@voila.Fr> a écrit dans le message de news:
452cd988$0$27395$ba4acef3@news.orange.fr...
Ceci m'amène à un autre problème que je trouve plutôt
délicat. Comment inverser deux éléments connus d'une liste
en un minimum de temps ? Exemple, j'ai une liste (de
pointeurs pour être exact), et je désirerai inverser deux
éléments de cette liste (et ne pas inverser le contenu des
pointeurs), d'autre part, dans le programme, d'autres
variables utilisent ces éléments.
Ça marche si ce qu'il a voulu dire, c'est de ne pas invalider
des pointeurs à des objets dont les pointeurs se trouvent dans
la liste. Sa mention de pointeurs rend la question un peu vague,
mais si on a des pointeurs à des éléments de la liste (quelque
soit le type d'élément -- des pointeurs à des pointeurs, donc,
si la liste contient des pointeurs), et qu'on veut qu'ils
pointent toujours au même objet, il faut faire quelque chose du
genre :
//! pre
//! pos1 et pos2 sont des itérateurs dans l.
//! pos1 != pos2.
// ---------------------------------------------------------------
template< typename T >
void
lswap(
std::list< T >& l,
typename std::list< T >::iterator
pos1,
typename std::list< T >::iterator
pos2 )
{
std::list< T > a ;
a.splice( a.begin(), l, pos1 ++ ) ;
std::list< T > b ;
b.splice( b.begin(), l, pos2 ++ ) ;
l.splice( pos1, b ) ;
l.splice( pos2, a ) ;
}
À la suite, les éléments à pos1 et à pos2 sont échangés, et tout
itérateur, pointeur ou référence qui désignait l'élément à pos1
le désigne encore, à sa nouvelle position, de même pour pos2.
(En fait, je suis sûr qu'on pourrait le faire avec une seule
liste temporaire, voire aucune :
mais je me sens pas sûr en ce qui concerne les cas limites, par
exemple quand pos1 et pos2 sont adjacents, et je trouve la
version avec deux temporaires bien plus simple à comprendre.)
------
Et lorsque qu'on ne connait pas à l'avance la position d'un élément ?
Comment fait-on pour la connaître ? Inévitablement, il va falloir parcourir
la liste ... non ?
"gg" a écrit dans le message de news: 452cd988$0$27395$
Ceci m'amène à un autre problème que je trouve plutôt délicat. Comment inverser deux éléments connus d'une liste en un minimum de temps ? Exemple, j'ai une liste (de pointeurs pour être exact), et je désirerai inverser deux éléments de cette liste (et ne pas inverser le contenu des pointeurs), d'autre part, dans le programme, d'autres variables utilisent ces éléments.
Ça marche si ce qu'il a voulu dire, c'est de ne pas invalider des pointeurs à des objets dont les pointeurs se trouvent dans la liste. Sa mention de pointeurs rend la question un peu vague, mais si on a des pointeurs à des éléments de la liste (quelque soit le type d'élément -- des pointeurs à des pointeurs, donc, si la liste contient des pointeurs), et qu'on veut qu'ils pointent toujours au même objet, il faut faire quelque chose du genre :
//! pre //! pos1 et pos2 sont des itérateurs dans l. //! pos1 != pos2. // --------------------------------------------------------------- template< typename T > void lswap( std::list< T >& l, typename std::list< T >::iterator pos1, typename std::list< T >::iterator pos2 ) { std::list< T > a ; a.splice( a.begin(), l, pos1 ++ ) ; std::list< T > b ; b.splice( b.begin(), l, pos2 ++ ) ; l.splice( pos1, b ) ; l.splice( pos2, a ) ; }
À la suite, les éléments à pos1 et à pos2 sont échangés, et tout itérateur, pointeur ou référence qui désignait l'élément à pos1 le désigne encore, à sa nouvelle position, de même pour pos2. (En fait, je suis sûr qu'on pourrait le faire avec une seule liste temporaire, voire aucune :
mais je me sens pas sûr en ce qui concerne les cas limites, par exemple quand pos1 et pos2 sont adjacents, et je trouve la version avec deux temporaires bien plus simple à comprendre.)
------
Et lorsque qu'on ne connait pas à l'avance la position d'un élément ? Comment fait-on pour la connaître ? Inévitablement, il va falloir parcourir la liste ... non ?
gg
Stephane Wirtel
gg wrote:
Quelle est la différence entre Std et Stl au niveau fonctionnel ? pas trop compris ce que tu demandes à part que STL est pour Standard
Template Library et que std est le namespace de la STL. Si c'est cela que tu demandais.
gg wrote:
Quelle est la différence entre Std et Stl au niveau fonctionnel ?
pas trop compris ce que tu demandes à part que STL est pour Standard
Template Library et que std est le namespace de la STL. Si c'est cela
que tu demandais.
Quelle est la différence entre Std et Stl au niveau fonctionnel ? pas trop compris ce que tu demandes à part que STL est pour Standard
Template Library et que std est le namespace de la STL. Si c'est cela que tu demandais.
kanze
gg wrote:
Quelle est la différence entre Std et Stl au niveau fonctionnel ?
C'est lié à l'histoire. La « STL », c'est la bibliothèque créée par Stepanov ; elle comportait des collections (mais pas de string), des itérateurs et des algorithmes. Elle a été adoptée en bonne partie, mais pas complètement, et avec certaines modifications mineur, par le comité de normalisation pour faire partie de la bibliothèque standard du C++. Bibliothèque qui comporte d'autres parties aussi, comme les flux d'entrées/sorties et les chaînes de caractères.
Aujourd'hui, dans la pratique, quand on dit STL, on veut dire la partie de la bibliothèque standard qui dérive du travail de Stepanov. Ce qui veut dire que c'est un sous-ensemble de la bibliothèque standard.
Std, je suppose, est une abbréviation pour Standard. Écrit tout en minuscules, c'est aussi l'espace référentiel dans lequel se trouve toute la bibliothèque standard (ou prèsque -- le peu de macros qui s'y trouvent, hérités de C, ne se trouve pas dans std::. Pour cause.)
-- 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
gg wrote:
Quelle est la différence entre Std et Stl au niveau fonctionnel ?
C'est lié à l'histoire. La « STL », c'est la bibliothèque
créée par Stepanov ; elle comportait des collections (mais pas
de string), des itérateurs et des algorithmes. Elle a été
adoptée en bonne partie, mais pas complètement, et avec
certaines modifications mineur, par le comité de normalisation
pour faire partie de la bibliothèque standard du C++.
Bibliothèque qui comporte d'autres parties aussi, comme les flux
d'entrées/sorties et les chaînes de caractères.
Aujourd'hui, dans la pratique, quand on dit STL, on veut dire la
partie de la bibliothèque standard qui dérive du travail de
Stepanov. Ce qui veut dire que c'est un sous-ensemble de la
bibliothèque standard.
Std, je suppose, est une abbréviation pour Standard. Écrit tout
en minuscules, c'est aussi l'espace référentiel dans lequel se
trouve toute la bibliothèque standard (ou prèsque -- le peu de
macros qui s'y trouvent, hérités de C, ne se trouve pas dans
std::. Pour cause.)
--
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
Quelle est la différence entre Std et Stl au niveau fonctionnel ?
C'est lié à l'histoire. La « STL », c'est la bibliothèque créée par Stepanov ; elle comportait des collections (mais pas de string), des itérateurs et des algorithmes. Elle a été adoptée en bonne partie, mais pas complètement, et avec certaines modifications mineur, par le comité de normalisation pour faire partie de la bibliothèque standard du C++. Bibliothèque qui comporte d'autres parties aussi, comme les flux d'entrées/sorties et les chaînes de caractères.
Aujourd'hui, dans la pratique, quand on dit STL, on veut dire la partie de la bibliothèque standard qui dérive du travail de Stepanov. Ce qui veut dire que c'est un sous-ensemble de la bibliothèque standard.
Std, je suppose, est une abbréviation pour Standard. Écrit tout en minuscules, c'est aussi l'espace référentiel dans lequel se trouve toute la bibliothèque standard (ou prèsque -- le peu de macros qui s'y trouvent, hérités de C, ne se trouve pas dans std::. Pour cause.)
-- 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
gg wrote:
[...]
Et lorsque qu'on ne connait pas à l'avance la position d'un élément ? Comment fait-on pour la connaître ? Inévitablement, il va falloir parcourir la liste ... non ?
On se sert de std::find ou de std::find_if. C'est la principe des listes. L'insertion et la suppression à un endroit arbitraire est facile, mais on le paie en temps de récherche.
-- 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
gg wrote:
[...]
Et lorsque qu'on ne connait pas à l'avance la position d'un
élément ? Comment fait-on pour la connaître ? Inévitablement,
il va falloir parcourir la liste ... non ?
On se sert de std::find ou de std::find_if. C'est la principe
des listes. L'insertion et la suppression à un endroit
arbitraire est facile, mais on le paie en temps de récherche.
--
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
Et lorsque qu'on ne connait pas à l'avance la position d'un élément ? Comment fait-on pour la connaître ? Inévitablement, il va falloir parcourir la liste ... non ?
On se sert de std::find ou de std::find_if. C'est la principe des listes. L'insertion et la suppression à un endroit arbitraire est facile, mais on le paie en temps de récherche.
-- 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
Alain Gaillard wrote:
très mauvaise idée
for (i=test.begin(); i!=test.end(); i++)
attention, ton code recalcule toujours la fin de ta collection, autant écrire ceci.
std::list< char * >::iterator it = test.begin(), itEnd = test.end(); for( it != itEnd; ++it ) { }
de plus, je vois que tu réalises une postincrémentation sur ton iterateur, ce qui n'est pas forcément judicieux. autant réaliser une préincrémentation sinon, ça économisera des ressources.
Voilà de quoi relancer un débat à peine clos, n'est-ce pas James ;)
Bof. Si Stephane a du temps à perdre, et est payé pour ne rien faire (ou ne travaille pour rien), ça pourrait se justifier. Pour les autres, évidemment : on attend que le profiler nous disent que c'est nécessaire. (En ce qui concerne la différence entre la préincrémentation et la postincrémentation, je n'ai pas encore réussi à trouver un cas où c'est mesurable. Certainement pas avec g++, en tout cas.)
-- 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
Alain Gaillard wrote:
très mauvaise idée
for (i=test.begin(); i!=test.end(); i++)
attention, ton code recalcule toujours la fin de ta
collection, autant écrire ceci.
std::list< char * >::iterator it = test.begin(), itEnd = test.end();
for( it != itEnd; ++it ) {
}
de plus, je vois que tu réalises une postincrémentation sur
ton iterateur, ce qui n'est pas forcément judicieux. autant
réaliser une préincrémentation sinon, ça économisera des
ressources.
Voilà de quoi relancer un débat à peine clos, n'est-ce pas James ;)
Bof. Si Stephane a du temps à perdre, et est payé pour ne rien
faire (ou ne travaille pour rien), ça pourrait se justifier.
Pour les autres, évidemment : on attend que le profiler nous
disent que c'est nécessaire. (En ce qui concerne la différence
entre la préincrémentation et la postincrémentation, je n'ai pas
encore réussi à trouver un cas où c'est mesurable. Certainement
pas avec g++, en tout cas.)
--
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
attention, ton code recalcule toujours la fin de ta collection, autant écrire ceci.
std::list< char * >::iterator it = test.begin(), itEnd = test.end(); for( it != itEnd; ++it ) { }
de plus, je vois que tu réalises une postincrémentation sur ton iterateur, ce qui n'est pas forcément judicieux. autant réaliser une préincrémentation sinon, ça économisera des ressources.
Voilà de quoi relancer un débat à peine clos, n'est-ce pas James ;)
Bof. Si Stephane a du temps à perdre, et est payé pour ne rien faire (ou ne travaille pour rien), ça pourrait se justifier. Pour les autres, évidemment : on attend que le profiler nous disent que c'est nécessaire. (En ce qui concerne la différence entre la préincrémentation et la postincrémentation, je n'ai pas encore réussi à trouver un cas où c'est mesurable. Certainement pas avec g++, en tout cas.)
-- 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
Stephane Wirtel
Voilà de quoi relancer un débat à peine clos, n'est-ce pas James ;)
Bof. Si Stephane a du temps à perdre, et est payé pour ne rien faire (ou ne travaille pour rien), ça pourrait se justifier. Pour les autres, évidemment : on attend que le profiler nous disent que c'est nécessaire. (En ce qui concerne la différence entre la préincrémentation et la postincrémentation, je n'ai pas encore réussi à trouver un cas où c'est mesurable. Certainement pas avec g++, en tout cas.)
Sympa de me descendre comme ça :d
Bon, arrêtons le débat, je risque d'être refroidit :-)
Stéphane
Voilà de quoi relancer un débat à peine clos, n'est-ce pas James ;)
Bof. Si Stephane a du temps à perdre, et est payé pour ne rien
faire (ou ne travaille pour rien), ça pourrait se justifier.
Pour les autres, évidemment : on attend que le profiler nous
disent que c'est nécessaire. (En ce qui concerne la différence
entre la préincrémentation et la postincrémentation, je n'ai pas
encore réussi à trouver un cas où c'est mesurable. Certainement
pas avec g++, en tout cas.)
Sympa de me descendre comme ça :d
Bon, arrêtons le débat, je risque d'être refroidit :-)
Voilà de quoi relancer un débat à peine clos, n'est-ce pas James ;)
Bof. Si Stephane a du temps à perdre, et est payé pour ne rien faire (ou ne travaille pour rien), ça pourrait se justifier. Pour les autres, évidemment : on attend que le profiler nous disent que c'est nécessaire. (En ce qui concerne la différence entre la préincrémentation et la postincrémentation, je n'ai pas encore réussi à trouver un cas où c'est mesurable. Certainement pas avec g++, en tout cas.)
Sympa de me descendre comme ça :d
Bon, arrêtons le débat, je risque d'être refroidit :-)
Stéphane
James Kanze
Stephane Wirtel wrote:
Voilà de quoi relancer un débat à peine clos, n'est-ce pas James ;)
Bof. Si Stephane a du temps à perdre, et est payé pour ne rien faire (ou ne travaille pour rien), ça pourrait se justifier. Pour les autres, évidemment : on attend que le profiler nous disent que c'est nécessaire. (En ce qui concerne la différence entre la préincrémentation et la postincrémentation, je n'ai pas encore réussi à trouver un cas où c'est mesurable. Certainement pas avec g++, en tout cas.)
Sympa de me descendre comme ça :d
Au moins tu es en bonne companie. C'est dans un article GotW que Herb Sutter a dit pour le premier de préférer les post-incrémentations aux pré, parce qu'elles généraient moins de temporaires. Étant de nature curieuse, j'ai écrit un petit benchmark et j'ai mesuré exactement combien ces temporaires supplémentaires coûtés. J'avais comme un vague soupçon que le coût n'était pas si élevé que ça, et que dans la plupart des cas, où on faisait quelque chose d'intéressant dans la boucle, il était insignificant. Mais j'avoue que j'étais surpris moi-même à découvrir que le coût était zéro, et ça pour tous les itérateurs défini dans la norme.
Herb n'avait pas parlé du coup de déplacer l'appel à end() en dehors de la boucle. J'ai mesuré ça aussi ; là en revanche, il y a bien un coût de faire l'appel chaque fois dans la boucle. Mais c'est un coût assez faible aussi, qui serait insignifiant dès qu'on fasse quoique ce soit dans la boucle.
(Herb a légèrement modifié son article par la suite, pour dire que le gain était souvent minime, mais qu'il n'y avait jamais de perte, et aussi pour citer la possibilité d'extraire l'appel à end() de la boucle.)
Enfin, le résultat de mes mesures m'amène à prendre une position très nuancée. Toute autre chose égal, j'utiliserai de préfèrence la pré-incrémentation. Mais cette préfèrence ne va pas jusqu'à faire différemment de ce qui est déjà fait dans du code existant, ni même d'arguer pour un changement des règles de codage, dans le cas où elles préscrivent la pré-incrémentation. (Historiquement, la pré-incrémentation avait la préférence, pour la simple raison que c'est ce qu'utilisait Kernighan et Richie dans leur livre.) Quant à extraire l'appel de end() de la boucle, c'est une écriture plus lourde, qui j'évite tant que le profileur ne me dit pas autrement. Chose qui n'est jamais arrivé jusqu'ici.
Pour la reste, évidemment, je ne critiquerais jamais quelqu'un parce qu'il préfère la pré-incrémentation. Mais qu'il prétend imposer son choix, et que l'alternative est pire, c'est autre chose.
-- 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
Stephane Wirtel wrote:
Voilà de quoi relancer un débat à peine clos, n'est-ce pas James ;)
Bof. Si Stephane a du temps à perdre, et est payé pour ne rien
faire (ou ne travaille pour rien), ça pourrait se justifier.
Pour les autres, évidemment : on attend que le profiler nous
disent que c'est nécessaire. (En ce qui concerne la différence
entre la préincrémentation et la postincrémentation, je n'ai pas
encore réussi à trouver un cas où c'est mesurable. Certainement
pas avec g++, en tout cas.)
Sympa de me descendre comme ça :d
Au moins tu es en bonne companie. C'est dans un article GotW que
Herb Sutter a dit pour le premier de préférer les
post-incrémentations aux pré, parce qu'elles généraient moins de
temporaires. Étant de nature curieuse, j'ai écrit un petit
benchmark et j'ai mesuré exactement combien ces temporaires
supplémentaires coûtés. J'avais comme un vague soupçon que le
coût n'était pas si élevé que ça, et que dans la plupart des
cas, où on faisait quelque chose d'intéressant dans la boucle,
il était insignificant. Mais j'avoue que j'étais surpris
moi-même à découvrir que le coût était zéro, et ça pour tous les
itérateurs défini dans la norme.
Herb n'avait pas parlé du coup de déplacer l'appel à end() en
dehors de la boucle. J'ai mesuré ça aussi ; là en revanche, il y
a bien un coût de faire l'appel chaque fois dans la boucle. Mais
c'est un coût assez faible aussi, qui serait insignifiant dès
qu'on fasse quoique ce soit dans la boucle.
(Herb a légèrement modifié son article par la suite, pour dire
que le gain était souvent minime, mais qu'il n'y avait jamais de
perte, et aussi pour citer la possibilité d'extraire l'appel à
end() de la boucle.)
Enfin, le résultat de mes mesures m'amène à prendre une position
très nuancée. Toute autre chose égal, j'utiliserai de préfèrence
la pré-incrémentation. Mais cette préfèrence ne va pas jusqu'à
faire différemment de ce qui est déjà fait dans du code
existant, ni même d'arguer pour un changement des règles de
codage, dans le cas où elles préscrivent la pré-incrémentation.
(Historiquement, la pré-incrémentation avait la préférence, pour
la simple raison que c'est ce qu'utilisait Kernighan et Richie
dans leur livre.) Quant à extraire l'appel de end() de la
boucle, c'est une écriture plus lourde, qui j'évite tant que le
profileur ne me dit pas autrement. Chose qui n'est jamais arrivé
jusqu'ici.
Pour la reste, évidemment, je ne critiquerais jamais quelqu'un
parce qu'il préfère la pré-incrémentation. Mais qu'il prétend
imposer son choix, et que l'alternative est pire, c'est autre
chose.
--
James Kanze Gabi Software email: kanze.james@neuf.fr
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
Voilà de quoi relancer un débat à peine clos, n'est-ce pas James ;)
Bof. Si Stephane a du temps à perdre, et est payé pour ne rien faire (ou ne travaille pour rien), ça pourrait se justifier. Pour les autres, évidemment : on attend que le profiler nous disent que c'est nécessaire. (En ce qui concerne la différence entre la préincrémentation et la postincrémentation, je n'ai pas encore réussi à trouver un cas où c'est mesurable. Certainement pas avec g++, en tout cas.)
Sympa de me descendre comme ça :d
Au moins tu es en bonne companie. C'est dans un article GotW que Herb Sutter a dit pour le premier de préférer les post-incrémentations aux pré, parce qu'elles généraient moins de temporaires. Étant de nature curieuse, j'ai écrit un petit benchmark et j'ai mesuré exactement combien ces temporaires supplémentaires coûtés. J'avais comme un vague soupçon que le coût n'était pas si élevé que ça, et que dans la plupart des cas, où on faisait quelque chose d'intéressant dans la boucle, il était insignificant. Mais j'avoue que j'étais surpris moi-même à découvrir que le coût était zéro, et ça pour tous les itérateurs défini dans la norme.
Herb n'avait pas parlé du coup de déplacer l'appel à end() en dehors de la boucle. J'ai mesuré ça aussi ; là en revanche, il y a bien un coût de faire l'appel chaque fois dans la boucle. Mais c'est un coût assez faible aussi, qui serait insignifiant dès qu'on fasse quoique ce soit dans la boucle.
(Herb a légèrement modifié son article par la suite, pour dire que le gain était souvent minime, mais qu'il n'y avait jamais de perte, et aussi pour citer la possibilité d'extraire l'appel à end() de la boucle.)
Enfin, le résultat de mes mesures m'amène à prendre une position très nuancée. Toute autre chose égal, j'utiliserai de préfèrence la pré-incrémentation. Mais cette préfèrence ne va pas jusqu'à faire différemment de ce qui est déjà fait dans du code existant, ni même d'arguer pour un changement des règles de codage, dans le cas où elles préscrivent la pré-incrémentation. (Historiquement, la pré-incrémentation avait la préférence, pour la simple raison que c'est ce qu'utilisait Kernighan et Richie dans leur livre.) Quant à extraire l'appel de end() de la boucle, c'est une écriture plus lourde, qui j'évite tant que le profileur ne me dit pas autrement. Chose qui n'est jamais arrivé jusqu'ici.
Pour la reste, évidemment, je ne critiquerais jamais quelqu'un parce qu'il préfère la pré-incrémentation. Mais qu'il prétend imposer son choix, et que l'alternative est pire, c'est autre chose.
-- 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
Gabriel Dos Reis
"James Kanze" writes:
| Stephane Wirtel wrote: | > >> Voilà de quoi relancer un débat à peine clos, n'est-ce pas James ;) | | > > Bof. Si Stephane a du temps à perdre, et est payé pour ne rien | > > faire (ou ne travaille pour rien), ça pourrait se justifier. | > > Pour les autres, évidemment : on attend que le profiler nous | > > disent que c'est nécessaire. (En ce qui concerne la différence | > > entre la préincrémentation et la postincrémentation, je n'ai pas | > > encore réussi à trouver un cas où c'est mesurable. Certainement | > > pas avec g++, en tout cas.) | | > Sympa de me descendre comme ça :d | | Au moins tu es en bonne companie. C'est dans un article GotW que | Herb Sutter a dit pour le premier de préférer les | post-incrémentations aux pré, parce qu'elles généraient moins de | temporaires.
ce n'est pas plutôt le contraire ?
[...]
| (Historiquement, la pré-incrémentation avait la préférence, pour ^^^
post
-- Gaby
"James Kanze" <kanze.james@neuf.fr> writes:
| Stephane Wirtel wrote:
| > >> Voilà de quoi relancer un débat à peine clos, n'est-ce pas James ;)
|
| > > Bof. Si Stephane a du temps à perdre, et est payé pour ne rien
| > > faire (ou ne travaille pour rien), ça pourrait se justifier.
| > > Pour les autres, évidemment : on attend que le profiler nous
| > > disent que c'est nécessaire. (En ce qui concerne la différence
| > > entre la préincrémentation et la postincrémentation, je n'ai pas
| > > encore réussi à trouver un cas où c'est mesurable. Certainement
| > > pas avec g++, en tout cas.)
|
| > Sympa de me descendre comme ça :d
|
| Au moins tu es en bonne companie. C'est dans un article GotW que
| Herb Sutter a dit pour le premier de préférer les
| post-incrémentations aux pré, parce qu'elles généraient moins de
| temporaires.
ce n'est pas plutôt le contraire ?
[...]
| (Historiquement, la pré-incrémentation avait la préférence, pour
^^^
| Stephane Wirtel wrote: | > >> Voilà de quoi relancer un débat à peine clos, n'est-ce pas James ;) | | > > Bof. Si Stephane a du temps à perdre, et est payé pour ne rien | > > faire (ou ne travaille pour rien), ça pourrait se justifier. | > > Pour les autres, évidemment : on attend que le profiler nous | > > disent que c'est nécessaire. (En ce qui concerne la différence | > > entre la préincrémentation et la postincrémentation, je n'ai pas | > > encore réussi à trouver un cas où c'est mesurable. Certainement | > > pas avec g++, en tout cas.) | | > Sympa de me descendre comme ça :d | | Au moins tu es en bonne companie. C'est dans un article GotW que | Herb Sutter a dit pour le premier de préférer les | post-incrémentations aux pré, parce qu'elles généraient moins de | temporaires.
ce n'est pas plutôt le contraire ?
[...]
| (Historiquement, la pré-incrémentation avait la préférence, pour ^^^
post
-- Gaby
James Kanze
Gabriel Dos Reis wrote:
"James Kanze" writes:
| Stephane Wirtel wrote: | > >> Voilà de quoi relancer un débat à peine clos, n'est-ce pas J ames ;)
| > > Bof. Si Stephane a du temps à perdre, et est payé pour ne rien | > > faire (ou ne travaille pour rien), ça pourrait se justifier. | > > Pour les autres, évidemment : on attend que le profiler nous | > > disent que c'est nécessaire. (En ce qui concerne la différence | > > entre la préincrémentation et la postincrémentation, je n'ai pas | > > encore réussi à trouver un cas où c'est mesurable. Certaineme nt | > > pas avec g++, en tout cas.)
| > Sympa de me descendre comme ça :d
| Au moins tu es en bonne companie. C'est dans un article GotW que | Herb Sutter a dit pour le premier de préférer les | post-incrémentations aux pré, parce qu'elles généraient moins de | temporaires.
ce n'est pas plutôt le contraire ?
[...]
| (Historiquement, la pré-incrémentation avait la préférence, pour ^^^
post
Tout à fait. J'ai inversé les deux ci-dessus.
-- 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
Gabriel Dos Reis wrote:
"James Kanze" <kanze.james@neuf.fr> writes:
| Stephane Wirtel wrote:
| > >> Voilà de quoi relancer un débat à peine clos, n'est-ce pas J ames ;)
| > > Bof. Si Stephane a du temps à perdre, et est payé pour ne rien
| > > faire (ou ne travaille pour rien), ça pourrait se justifier.
| > > Pour les autres, évidemment : on attend que le profiler nous
| > > disent que c'est nécessaire. (En ce qui concerne la différence
| > > entre la préincrémentation et la postincrémentation, je n'ai pas
| > > encore réussi à trouver un cas où c'est mesurable. Certaineme nt
| > > pas avec g++, en tout cas.)
| > Sympa de me descendre comme ça :d
| Au moins tu es en bonne companie. C'est dans un article GotW que
| Herb Sutter a dit pour le premier de préférer les
| post-incrémentations aux pré, parce qu'elles généraient moins de
| temporaires.
ce n'est pas plutôt le contraire ?
[...]
| (Historiquement, la pré-incrémentation avait la préférence, pour
^^^
post
Tout à fait. J'ai inversé les deux ci-dessus.
--
James Kanze (Gabi Software) email: kanze.james@neuf.fr
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
| Stephane Wirtel wrote: | > >> Voilà de quoi relancer un débat à peine clos, n'est-ce pas J ames ;)
| > > Bof. Si Stephane a du temps à perdre, et est payé pour ne rien | > > faire (ou ne travaille pour rien), ça pourrait se justifier. | > > Pour les autres, évidemment : on attend que le profiler nous | > > disent que c'est nécessaire. (En ce qui concerne la différence | > > entre la préincrémentation et la postincrémentation, je n'ai pas | > > encore réussi à trouver un cas où c'est mesurable. Certaineme nt | > > pas avec g++, en tout cas.)
| > Sympa de me descendre comme ça :d
| Au moins tu es en bonne companie. C'est dans un article GotW que | Herb Sutter a dit pour le premier de préférer les | post-incrémentations aux pré, parce qu'elles généraient moins de | temporaires.
ce n'est pas plutôt le contraire ?
[...]
| (Historiquement, la pré-incrémentation avait la préférence, pour ^^^
post
Tout à fait. J'ai inversé les deux ci-dessus.
-- 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