copy() pour un deque ? - C++ - Programmation
Marsh Posté le 05-05-2003 à 15:55:59
tu m'as l'air d'etre nouveau ici, donc je te previens qu'il existe des balises cpp tres utile
(sort nous le code fautif aussi, ca peut ptet aider, paske les erreurs quand y'a des template c generalement assez imbitable )
Marsh Posté le 05-05-2003 à 16:01:26
chrisbk a écrit : tu m'as l'air d'etre nouveau ici, donc je te previens qu'il existe des balises cpp tres utile |
ba je fais juste un :
copy( source.overlaps_.begin(), source.overlaps_.end(), overlaps_);
avec overlaps_ qui est un std::deque<vceOverlapCL*>, mais le compilo a pas l'air d'aimer des masses
apres avoir remis l'ancien code, il m'a meme sorti :
|
Marsh Posté le 05-05-2003 à 16:23:26
ben il faut donner un iterator pour le 3ième argument, mais ça n'agrandira pas ta sequence de destination
si ta sequende de destiantion ne fait pas la taille souhaitée, soit tu fais un resize(source.size()) (le plus efficace), soit u peux jouer avec les inserter
Marsh Posté le 05-05-2003 à 16:29:25
ok donc a priori pour le troisieme argument je lui passe
std::deque<vceOverlapCL*>::const_iterator iter |
et avant je fais un overlaps_.resize(source.overlaps_.size()) ?
autant laisser le code d'origine qui creait un iterateur, parcourait chaque element du deque et le copiait via un overlaps_.push_back(new vceOverlapCL(*(*iter))) dans overlaps_ non ? (je cherche le plus efficace niveau perf)
Marsh Posté le 05-05-2003 à 16:30:43
ben nom, par ce que les push_back implique des redimensionnement. avec resize, il n'y en qu'un seul
Marsh Posté le 05-05-2003 à 16:43:18
heu comment je relie mon const_iterator a overlaps_ dans mon copy
Marsh Posté le 05-05-2003 à 16:48:55
petit exemple en passant
Code :
|
wait, je resout ton problème
Marsh Posté le 05-05-2003 à 16:51:48
eh bien pourkoi ne pas essayer
copy(truc.begin(), truc.end(), inserter(conteneur_dest, iterateur_de_ce_conteneur)
qui inserera les elements de truc avant l'iterateur donné?
exemple
Code :
|
il va de soi que ici, un vector<T>::iterator etant assimilé à un vector<T>::value_type *, &b[1] est donc un iterateur valide
Marsh Posté le 05-05-2003 à 16:55:29
si j'ai bien compris ton exemple a priori j'ai juste a faire :
copy(source.overlaps_.begin(), source.overlaps_.end(), overlaps_.begin());
Marsh Posté le 05-05-2003 à 16:57:33
oui, pour peu que overlaps_ soit de bonne taille, grace a resize comme montré plus haut
dis donc toi, tu serais pas en train de nous pondre un constructeur par recopie? par ce que les conteneurs peuvent etre construits directement à partir de sequence
conteneur(truc.begin(), truc.end())
Marsh Posté le 05-05-2003 à 16:58:33
en fait je fais un
vceOverlapsCL& vceOverlapsCL::operator=(vceOverlapsCL const& source) |
Marsh Posté le 05-05-2003 à 17:09:28
soit une classe
Code :
|
Marsh Posté le 05-05-2003 à 17:39:53
ok donc tu copies dans tmp chaque membre de la source, et ensuite tu swappes les valeurs copiees avec les valeurs de la classe courante ?
et le constructeur sait de base comment faire overlaps_(source.overlaps_) ?
Marsh Posté le 05-05-2003 à 17:42:08
oui, c'est ça!! et à marche au poil!
et pour overlaps_(source.overlaps_) , ça t'arrive de lire là doc? bien sur que ça recopie correctement!!!!
Marsh Posté le 05-05-2003 à 17:46:24
++Taz a écrit : oui, c'est ça!! et à marche au poil! |
ouais desole pour la question con, je m'en suis rendu compte trop tard
c'est la methode la plus efficace pour toi ?
Marsh Posté le 05-05-2003 à 17:47:35
bon, j'espère que t'as les réponses à tes questions. si t'as besoin de conseils pour des optimisations propres hesite pas
Marsh Posté le 05-05-2003 à 18:00:16
l'astuce du swap est génial, mais il y en a une autre, toujours avec swap
souvent dans une fonction, on travaille avec un conteneur temporaire et à un moment ou un autre on doit recopier ce contenu dans son paramètre ou son membre
genre
Code :
|
c'est bien, mais étant donné qu'on ne sert plus de tmp, ça provoque une recopie via l'operator= (ce qui peut amner à unde déallocation, une rallocation et la recopie en elle-meme) ce qui n'est pas idéal des que ça prend du poids. l'astuce
Code :
|
et voilou!!! juste un passe-passe de pointeur
j'utilise ça tres tres souvent, c'est que du bonheur
pour moi, c'est vraiment super important de définir une fonction membre swap,c 'est tellement facile à écrire,e t le gain à l'utilisation est spectaculaire
Marsh Posté le 05-05-2003 à 18:02:52
j'ai un soucis, le compilo croit que j'appelle le swap de vceOverlapCL, faut que je rajoute std:: devant ?
Marsh Posté le 05-05-2003 à 18:08:49
techniquement les deque ont déjà un membre swap et surcharge comme ça std::swap<...>(a, b){ a.swap(b);}
Marsh Posté le 05-05-2003 à 18:16:22
ok, j'ai juste ecrit ca :
Code :
|
Marsh Posté le 05-05-2003 à 19:16:15
Mais je me pose la question du gain réel de perf quand même
Quand on fait appel au contructeur pour copier les valeurs dans tmp, ca revient à faire le copy() non ?
Ensuite on fait une opération de swap supplémentaire donc y a vraiment un gain
Marsh Posté le 05-05-2003 à 19:25:44
non y a carrément du gain
pour mon exemple avec tmp, je parles des cas ou est on est obligé de passer par une autra variable.Et copy et beaucoup plus lent que n'importe quel constructeur de recopie
sinon pour operator= à base de swap et constructeur par recopie, le gain est surtout en terme de temps, fait j'ai toujorus constaté ung ain de vitesse de minimum 5%
donc y a bon!
fait moi confiance, toi qui aime les optimisations, celle la est on ne peut plus simple à appliquer, elle ne fout pas en l'air la lisiblité du code (bien au contraire) et est tres payantes (j'ai bossé avec des pseudo chaine deplusieurs centaines de milliers de caracteres, et la différence est enorme
Marsh Posté le 06-05-2003 à 09:06:33
ok, je savais pas pour le copy plus lent que le constructeur de recopie, ca explique tout dans ce cas.
Et ca m'économise le resize également
Marsh Posté le 06-05-2003 à 09:10:28
tient d'ailleurs si j'avais fait un std::swap(tmp); au lieu du swap(tmp);, il aurait fonctionné par copie, c'est bien ca ?
Marsh Posté le 06-05-2003 à 09:34:12
tu veux dire std::swap(a, b) au lieu de a.swap(b)
ben std::swap est par défaut
Code :
|
ça convient tres bien pour tous les usages . mes les designers de la STL on eu la bonne idée de spécialiser le template pour chaque classe ayant une fonction membre swap
donc tu peux utliser std::swap sans problème dans tous les cas. si tu as des toutes sur l'implémentation de ta lib, ben le mieux, c'est encore d'ecire a.swap(b) explicitement
Marsh Posté le 06-05-2003 à 09:57:45
non je voulais dire plutot que de reecrire ma propre fonction swap, utiliser celle de la STL
Marsh Posté le 06-05-2003 à 15:45:25
ben celle de STL elle fait ce que je t'ai dit, c'est à dire des recopies. comment voudrait tu que STL sache faire un swap par passe-passe de pointeur dans tes classes à toi. elle fait la menière générique qui marche à tous les cous. à toi de la spécialiser et d'en profiter
Marsh Posté le 05-05-2003 à 15:54:16
ca existe pas ?
mon compilo me sort :
"/opt/SUNWspro/v6.1/SUNWspro/WS6U1/include/CC/Cstd/./algorithm.cc", line 427: Error: The operation "++ std::deque<vceOverlapCL*, std::allocator<vceOverlapCL*>>" is illegal.
"overlap.cpp", line 51: Where: While instantiating "std::copy<std::deque<vceOverlapCL*, std::allocator<vceOverlapCL*>>::const_iterator, std::deque<vceOverlapCL*, std::allocator<vceOverlapCL*>>>(std::deque<vceOverlapCL*, std::allocator<vceOverlapCL*>>::const_iterator, std::deque<vceOverlapCL*, std::allocator<vceOverlapCL*>>::const_iterator, std::deque<vceOverlapCL*, std::allocator<vceOverlapCL*>> )".
"overlap.cpp", line 51: Where: Instantiated from non-template code.
1 Error(s) detected.
Message édité par joce le 05-05-2003 à 15:54:49