problème avec for_each

problème avec for_each - C++ - Programmation

Marsh Posté le 05-08-2004 à 15:19:33    

Bonjour, j'ai une erreur avec le code suivant :
 

Code :
  1. class format_stack
  2. {
  3.  bool bfirst; // 1ere insertion ?
  4.  std::ostringstream oss;
  5. public:
  6.  format_stack()
  7.   : bfirst(true)
  8.  {
  9.  }
  10.  void operator () (const std::string &s)
  11.  {
  12.   if(bfirst)
  13.    bfirst = false;
  14.   else
  15.    oss << " -> ";
  16.   oss << s;
  17.  }
  18.  std::string get() const
  19.  {
  20.   return oss.str();
  21.  }
  22. };
  23.  std::list<std::string> l;
  24.  l.push_back(std::string("1" ));
  25.  l.push_back(std::string("2" ));
  26.  format_stack fs;
  27.  std::for_each(l.rbegin(), l.rend(), fs);


 
compilé avec visual studio 2003
 
a cette ligne : std::for_each(l.rbegin(), l.rend(), fs);
error C2664: 'std::for_each' : impossible de convertir le paramètre 3 de 'black::stack_trace::format_stack' en
'black::stack_trace::format_stack'
 
Je suppose que c'est un problème de prototype de l'opérateur () du foncteur, mais je n'arrive pas à trouver ...
Toute aide est bienvenue, merci :)


Message édité par blackgoddess le 05-08-2004 à 15:20:01

---------------
-( BlackGoddess )-
Reply

Marsh Posté le 05-08-2004 à 15:19:33   

Reply

Marsh Posté le 05-08-2004 à 15:38:57    

moi je dirais qu'il apprécie pas trop la copie de stream (mais j'ai pas testé, j'ai pas de compilo c++ au boulot)
 
cela dit moi j'aurais plutot fait avec un std::copy + iterator perso

Reply

Marsh Posté le 05-08-2004 à 15:47:17    

ou transform en fait !

Reply

Marsh Posté le 05-08-2004 à 16:18:41    

c'était effectivement la copie de stream qu'il n'aimait pas.
 
j'y suis arrivé comme ca :
 

Code :
  1. class format_stack
  2. {
  3.  bool bfirst; // 1ere insertion ?
  4.  std::ostringstream & oss;
  5. public:
  6.  format_stack(std::ostringstream & s)
  7.   : bfirst(true), oss(s)
  8.  {
  9.  }
  10.  void operator () (const std::string &s)
  11.  {
  12.   if(bfirst)
  13.    bfirst = false;
  14.   else
  15.    oss << " -> ";
  16.   oss << s;
  17.  }
  18. };
  19.  std::list<std::string> l;
  20.  l.push_back(std::string("1" ));
  21.  l.push_back(std::string("2" ));
  22.  std::ostringstream oss;
  23.  std::for_each(l.rbegin(), l.rend(), format_stack(oss));


 
j'ai essayé avec tranform, mais je n'y suis pas arrivé :
je ne vois pas comment remplir un std::string (ou std::ostreamstring ou autre)
à partir d'un std::list<std::string>
 
aurais-tu un petit exemple stp ?


Message édité par blackgoddess le 05-08-2004 à 16:19:16

---------------
-( BlackGoddess )-
Reply

Marsh Posté le 05-08-2004 à 16:38:41    

ben un stingstream, c'est un stream, tu peux très bien faire
 
* istream_iterator<string>(in)++ = "hello";

Reply

Marsh Posté le 06-08-2004 à 17:27:21    

Hormis le pb de compilation, il me semble que ton functor etait mal conçu. La valeur de oss appartenant à l'instance fs n'est pas modifiée par le for_each. Je me trompe ?
 
 
 

Code :
  1. #include<iostream>
  2. #include<string>
  3. #include<list>
  4. using namespace std;
  5. class format_stack
  6. {
  7. string& os;
  8. public:
  9. format_stack( string& s ) : os(s) {}
  10. void operator() ( const string& s ) const {
  11.  if( os.size() != 0 )
  12.   os += " -> ";
  13.  os += s;
  14. }
  15. };
  16. int main()
  17. {
  18. list<std::string> l;
  19. l.push_back( "1" );
  20. l.push_back( "2" );
  21. string s;
  22. for_each( l.rbegin(), l.rend(), format_stack(s) );
  23. cout << s << endl;
  24. }


Message édité par xterminhate le 06-08-2004 à 17:34:30

---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 06-08-2004 à 17:43:55    

la méthode que j'ai mise ci-dessus fonctionne (edit : a l'exécution aussi), en effet l'objet ostringstream est passé par référence.
 
au niveau de l'optimisation, il veut mieux remplir un std::ostringstream ou un std::string pour des concaténations comme ca ?


Message édité par blackgoddess le 06-08-2004 à 17:46:15

---------------
-( BlackGoddess )-
Reply

Marsh Posté le 06-08-2004 à 17:51:48    

J'ai préféré le string parce qu'aucune conversion n'etait nécessaire dans ton cas d'utilisation (juste concaténation). Niveau optimisation, je ne sais pas dire exactement.... je pencherais pour string plus rapide que ostringstream ! En attendant Taz, tu paries sur quoi ? ;)


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 06-08-2004 à 17:56:47    

ben t'as pas besoin d'un ostringstream pour concaténer des string. ni même de foreach

Reply

Marsh Posté le 06-08-2004 à 17:57:14    

je suppose que le std::string ralloue son buffer a chaque concaténation, ce qui n'est peut-être pas le cas d'un buffer de stream ... donc je voterais ostringstream plus rapide :p


---------------
-( BlackGoddess )-
Reply

Marsh Posté le 06-08-2004 à 17:57:14   

Reply

Marsh Posté le 06-08-2004 à 18:12:50    

tu supposes mal à priori

Reply

Marsh Posté le 06-08-2004 à 18:25:52    

Un gage, un gage, un gage ! :p


---------------
Cordialement, Xterm-in'Hate...
Reply

Marsh Posté le 09-08-2004 à 11:03:48    

Et pourquoi pas une simple petite fonction templatee qui utilise un ostream_iterator :

Code :
  1. template<typename Iter>
  2. std::string format_stack( Iter First, Iter Last )
  3. {
  4.     std::ostringstream oss;
  5.     std::copy(
  6.         First,
  7.         --Iter( Last ),
  8.         std::ostream_iterator<std::string>( oss, "->" ) );
  9.     oss << *(--Last);
  10.     return oss.str();
  11. }
  12. int main()
  13. {
  14.     std::list<std::string> l;
  15.     l.push_back( "1" );
  16.     l.push_back( "2" );
  17.     l.push_back( "3" );
  18.     l.push_back( "4" );
  19.     std::cout << format_stack( l.begin(), l.end() ) << '\n';
  20.     std::cout << format_stack( l.rbegin(), l.rend() ) << '\n';
  21. }


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 09-08-2004 à 11:10:00    

je penser à un truc comem effectivement

Reply

Marsh Posté le 09-08-2004 à 20:12:11    

ah voui en effet mci pour cette solution :)
 
xterminate => jdois courir en slip a travers le forum ? :p


---------------
-( BlackGoddess )-
Reply

Marsh Posté le 09-08-2004 à 20:20:57    

HelloWorld > solution séduisante !  :jap:  
 
BlackGoddess > En cette période estivale, le string est de rigueur ! :)


---------------
Cordialement, Xterm-in'Hate...
Reply

Sujets relatifs:

Leave a Replay

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