copy() pour un deque ?

copy() pour un deque ? - C++ - Programmation

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
Reply

Marsh Posté le 05-05-2003 à 15:54:16   

Reply

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 [:ddr555]
 
(sort nous le code fautif aussi, ca peut ptet aider, paske les erreurs quand y'a des template c generalement assez imbitable :/)

Reply

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 [:ddr555]
 
(sort nous le code fautif aussi, ca peut ptet aider, paske les erreurs quand y'a des template c generalement assez imbitable :/)


 
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 :D
 
apres avoir remis l'ancien code, il m'a meme sorti :
 


ar: cannot open /export/rcsstore/5.0.2_030425_vce/tools.sun4v/dfII/group/vce/src/connaware/SunWS_cache/CC_obj_4/4bo2Eqxf2Tc1WRqFO_5e.o
 No such file or directory
ar: /export/rcsstore/5.0.2_030425_vce/tools.sun4v/dfII/group/vce/src/connaware/SunWS_cache/CC_obj_4/4bo2Eqxf2Tc1WRqFO_5e.o not found
__1cDstdEcopy4n0AFdeque4CpnMvceOverlapCL_n0AJallocator4C2___Oconst_iterator_n0D__6FTA4TB_5_ is out-of-date and will be regenerated
*** Error code 1


 
[:ddr555]


Message édité par joce le 05-05-2003 à 16:01:53
Reply

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
 

Reply

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)


Message édité par joce le 05-05-2003 à 16:30:02
Reply

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

Reply

Marsh Posté le 05-05-2003 à 16:35:47    

interessant je vais tester ca :)

Reply

Marsh Posté le 05-05-2003 à 16:43:18    

heu comment je relie mon const_iterator a overlaps_ dans mon copy :??:

Reply

Marsh Posté le 05-05-2003 à 16:48:55    

petit exemple en passant
 

Code :
  1. #include <list>
  2. #include <deque>
  3. #include <vector>
  4. #include <queue>
  5. #include <cassert>
  6. #include <iostream>
  7. #include <iterator>
  8. #include <ctime>
  9. #include <cstdlib>
  10. using namespace std;
  11. const size_t N=3;
  12. int main()
  13. {
  14.   srand(time(NULL));
  15.   list<int> liste;
  16.   for(size_t i=0; i<N; ++i)
  17.     {
  18.       liste.push_back(rand());
  19.     }
  20. //   copy(liste.begin(), liste.end(), ostream_iterator<int>(cout, "." ));
  21.   deque<int> dek;
  22.   dek.resize(liste.size());
  23.   copy(liste.begin(), liste.end(), dek.begin());
  24.   assert("sequences differentes" &&
  25.  !lexicographical_compare(liste.begin(), liste.end(), dek.begin(), dek.end()) &&
  26.  !lexicographical_compare(dek.begin(), dek.end(), liste.begin(), liste.end())
  27.  );
  28.  
  29.   vector<int> vek;
  30.   copy(liste.begin(), liste.end(), back_inserter(vek));
  31.   // existe aussi front_inserter pour les containers qui le supporte
  32.   assert("sequences differentes" &&
  33.  !lexicographical_compare(liste.begin(), liste.end(), vek.begin(), vek.end()) &&
  34.  !lexicographical_compare(vek.begin(), vek.end(), liste.begin(), liste.end())
  35.  );
  36.   cout << "Tout va tres bien...\n";
  37. }


 
 
wait, je resout ton problème

Reply

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 :
  1. vector<int> a(3, 42), b(2, 69);
  2. copy(a.begin(), a.end(), inserter(b, &b[1]));
  3. copy(b.begin(), b.end(), ostream_iterator<int>(cout, "." ));


 
il va de soi que ici, un vector<T>::iterator etant assimilé à un vector<T>::value_type *, &b[1] est donc un iterateur valide


Message édité par Taz le 05-05-2003 à 16:56:07
Reply

Marsh Posté le 05-05-2003 à 16:51:48   

Reply

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());


Message édité par joce le 05-05-2003 à 16:57:36
Reply

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())


Message édité par Taz le 05-05-2003 à 16:57:52
Reply

Marsh Posté le 05-05-2003 à 16:58:33    

en fait je fais un

vceOverlapsCL& vceOverlapsCL::operator=(vceOverlapsCL const& source)


Message édité par joce le 05-05-2003 à 17:02:19
Reply

Marsh Posté le 05-05-2003 à 17:03:07    

tu veux un tip de programmer C++?

Reply

Marsh Posté le 05-05-2003 à 17:09:28    

soit une classe
 

Code :
  1. class Foo
  2. {
  3.   Type membre;
  4.   // plein de membres
  5.   Foo();
  6.   Foo(const Foo &);
  7.   swap(Foo &);
  8.   const Foo & operator=(const Foo &);
  9. };
  10. //on a donc
  11. Foo:Foo()
  12. {}
  13. Foo::Foo(const Foo &rhs)
  14.   : membre(rhs.membre) // ...
  15. {}
  16. Foo::swap(Foo &rhs)
  17. {
  18.   // pour chaque membre
  19.   swap(membre, rhs.membre)
  20.   // pour ça il est bon de surcharger son swap
  21.   // ce qui permet d'optimiser
  22.   // en swappant des pointeurs, sinon par defaut
  23.   // swap fait par copie
  24. }
  25. const Foo & Foo::operator=(const Foo &rhs)
  26. {
  27.   Foo tmp(rhs);
  28.   swap(tmp);
  29.   return *this;
  30.   // et c'est tout!
  31.   // bref on a pas réécrit une constructeur de recopie
  32. }


 
 

Reply

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_) ?

Reply

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!!!!

Reply

Marsh Posté le 05-05-2003 à 17:46:24    

++Taz a écrit :

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!!!!


ouais desole pour la question con, je m'en suis rendu compte trop tard :D
c'est la methode la plus efficace pour toi ?


Message édité par joce le 05-05-2003 à 17:47:00
Reply

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

Reply

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 :
  1. void Foo:f()
  2. {
  3.   Conteneur tmp;
  4.   // faire semblant de travailler
  5.   //voilà fini
  6.   mon_membre=tmp;
  7. }


 
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 :
  1. mom_membre.swap(tmp)


 
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


Message édité par Taz le 05-05-2003 à 18:00:39
Reply

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 ?

Reply

Marsh Posté le 05-05-2003 à 18:06:54    

bon ca passe avec le std::, cool :)

Reply

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);}

Reply

Marsh Posté le 05-05-2003 à 18:16:22    

ok, j'ai juste ecrit ca :
 

Code :
  1. void vceOverlapsCL::swap(vceOverlapsCL &source)
  2. {
  3.       std::swap(hierFig_, source.hierFig_);
  4.       std::swap(overlapLayer_, source.overlapLayer_);
  5.       std::swap(overlaps_, source.overlaps_);
  6. }


Message édité par joce le 05-05-2003 à 18:16:41
Reply

Marsh Posté le 05-05-2003 à 18:18:00    

:) c'est OK

Reply

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 :??:

Reply

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


Message édité par Taz le 05-05-2003 à 19:38:45
Reply

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 :)

Reply

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 ?

Reply

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 :
  1. template<class T>
  2. void std::swap(T &a, T &b)
  3. {
  4.   T tmp(a);
  5.    a=b;
  6.    b=tmp;
  7. }


 
ç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

Reply

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

Reply

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

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed