ostream_iterator

ostream_iterator - C++ - Programmation

Marsh Posté le 21-03-2009 à 04:30:07    

Hi,
 
 

Code :
  1. #include <fstream>
  2. #include <vector>
  3. #include <iostream>
  4. #include <sstream>
  5. #include <iterator>
  6. struct MaClasse
  7. {
  8.  MaClasse(int m=0):m_(m){}
  9.  friend std::ostream& operator<<(std::ostream& o,const MaClasse & m);
  10.  std::string get()
  11.  {
  12.   ss_ << m_;
  13.   return ss_.str();
  14.  }
  15. private:
  16.  std::stringstream ss_;
  17.  int m_;
  18. };
  19. std::ostream& operator<<(std::ostream& o,const MaClasse & m)
  20. {
  21. o << m.get();
  22. return o;
  23. }
  24. void main()
  25. {
  26. std::vector<MaClasse> Tab1;
  27. MaClasse z;
  28. Tab1.push_back(z);
  29. std::ostream_iterator<MaClasse>(cout) output;
  30. std::copy(Tab1.begin(),Tab1.end(), output);
  31. system("pause" );
  32. }


 
Pourquoi est ce que ce code ne marche pas ?    le compilateur m'indique :  
 
error C2662: 'MaClasse::get' : impossible de convertir un pointeur 'this' de 'const MaClasse' en 'MaClasse &'
 
 
Merci


---------------

Reply

Marsh Posté le 21-03-2009 à 04:30:07   

Reply

Marsh Posté le 21-03-2009 à 08:25:00    

get n'est pas const ...

Message cité 1 fois
Message édité par Joel F le 21-03-2009 à 08:25:09
Reply

Marsh Posté le 21-03-2009 à 09:39:11    

pourquoi friend ?

Reply

Marsh Posté le 21-03-2009 à 14:32:04    

Joel F a écrit :

get n'est pas const ...


 
et quand je mets get const , ça m'emmène dans d'autre problème, je modifie le stringstream, donc je dois le déclarer mutable ? si oui j'ai encore d'autre problème, concernant les constructeur de recopie et = qui ne sont pas accesible, j'essaye d'encapsuler ça dans un auto_ptr, mais ça ne marche pas mieux...
 
 
@Taz: pourquoi friend, oui je sais que l'utilisation des friend n'est pas souvent une bonne idée, là c'est juste que je me rappel plus de la syntaxe qui permet de s'en passer


---------------

Reply

Marsh Posté le 21-03-2009 à 14:48:24    

bon avec le code ci-dessous ça marche, mais y pas plus simple/propre :
 

Code :
  1. #include <vector>
  2. #include <iostream>
  3. #include <sstream>
  4. #include <iterator>
  5. using std::cout;
  6. using std::stringstream;
  7. using std::ostream;
  8. using std::swap;
  9. template <typename T> struct ValeurInit;
  10. template <> struct ValeurInit<int>         {static int Init()         {return 0;}};
  11. template <> struct ValeurInit<std::string> {static std::string Init() {return "";}};
  12. template <typename T>
  13. struct MaClasse
  14. {
  15. explicit MaClasse(T m=ValeurInit<T>::Init()):
  16.    m_(m)
  17.    ,ss_(std::auto_ptr<stringstream>(new stringstream())){}
  18.  MaClasse(const MaClasse& m):m_(m.m_),ss_(m.ss_) {}
  19.  void Swap(MaClasse & mwc)
  20.  {
  21.   std::swap(ss_,mwc.ss_);
  22.   std::swap(m_,mwc.m_);
  23.  }
  24.  MaClasse& operator =(MaClasse  m)
  25.  {
  26.    Swap(m);
  27.    return *this;
  28.  }
  29.  void print (ostream& o) const
  30.  {
  31.   o<<get();
  32.  }
  33.  std::string get() const
  34.  {
  35.    *ss_ << m_;
  36.    return ss_->str();
  37.  }
  38. private:
  39.   mutable std::auto_ptr<stringstream>  ss_;
  40.  T m_;
  41. };
  42. template<class T>
  43. std::ostream& operator<<(std::ostream& o,const MaClasse<T> & m)
  44. {
  45. m.print(o);
  46. return o;
  47. }
  48. void main()
  49. {
  50.        typedef MaClasse<int> MyI
  51. MyI z(9);
  52. std::vector< MyI > Tab1;
  53. Tab1.push_back(z);
  54. std::copy(Tab1.begin(),Tab1.end(), std::ostream_iterator< MyI >(cout));
  55. }


Message édité par weblook$$ le 23-03-2009 à 01:02:06

---------------

Reply

Marsh Posté le 21-03-2009 à 16:06:57    

et d'ailleurs je ne comprends pas pourquoi je ss obligé d'écrire un const de copie et =, si je ne les écris pas , le compilo me marque :
 
struct 'MaClasse<T>' : pas de constructeur de copie disponible ou le constructeur de copie est déclaré 'explicit'
 
PS: ok pour le friend, il suffit d'ajouter une methode print(ostream& o) à la place

Message cité 1 fois
Message édité par weblook$$ le 21-03-2009 à 16:15:42

---------------

Reply

Marsh Posté le 21-03-2009 à 17:00:30    

# void Swap(const MaClasse<T> & m)
#  {
#   MaClasse<T> mwc = *const_cast<MaClasse<T>*>(&m);
#   swap(m_,mwc.m_);
#   swap(ss_,mwc.ss_);
#  }
 
t'as pas l'impression de faire n'importe quoi là ?

Reply

Marsh Posté le 21-03-2009 à 17:02:37    

:( oui ça m'a l'air un peu saboté, mais comment faire alors ?? au niveau du const jss coincé.

 

Oui bon effectivement en faisant des affectations au lieu des swap, ça roule, mais j'avais cru comprendre que de swappé c'était plus safe


Message édité par weblook$$ le 21-03-2009 à 17:35:38

---------------

Reply

Marsh Posté le 21-03-2009 à 20:35:08    

weblook$$ a écrit :

et d'ailleurs je ne comprends pas pourquoi je ss obligé d'écrire un const de copie et =, si je ne les écris pas , le compilo me marque :

 

struct 'MaClasse<T>' : pas de constructeur de copie disponible ou le constructeur de copie est déclaré 'explicit'

 

Le constructeur de recopie par défaut est déclaré explicit, et la classe vector à besoin d'un construeur de recopie qui ne le soit pas ?


Message édité par weblook$$ le 21-03-2009 à 21:01:38

---------------

Reply

Marsh Posté le 22-03-2009 à 15:51:40    

personne pour/confirmer infirmer  :( ?


---------------

Reply

Marsh Posté le 22-03-2009 à 15:51:40   

Reply

Marsh Posté le 22-03-2009 à 16:02:32    

c'ets le auto_ptr qui est non-copiable ...


Message édité par Joel F le 22-03-2009 à 16:02:58
Reply

Marsh Posté le 22-03-2009 à 17:44:27    

Lorsque je regarde l'implémenation de auto_ptr dans memory... le constructeur de recopie est public, donc je comprends pas ta réponse

 


Dans cet article , auto_ptr est copié sans problème...

 
Code :
  1. class MyClass
  2.   {
  3.     auto_ptr<Widget> w_; // hold the unsafe-to-copy
  4.                          //  Widget at arm's length
  5.   public:
  6.     void Swap( MyClass& other ) throw()
  7.     {
  8.       auto_ptr<Widget> temp( w_ );
  9.       w_ = other.w_;
  10.       other.w_ = temp;
  11.     }
  12.     MyClass& operator=( const MyClass& other )
  13.     {
  14.       /* canonical form */
  15.     }
  16.     // ... destruction, copy construction,
  17.     //     and copy assignment ...
  18.   };


Message édité par weblook$$ le 23-03-2009 à 02:12:51

---------------

Reply

Marsh Posté le 22-03-2009 à 23:50:24    

1) c'est bon problème localisé , le problème vient du fait que le constructeur de recopie dans la classe auto_ptr à un paramètre non const, et pour vector, du moins pour insérer des éléments dans une classe de type vector, il faut que la classe stockée ait un constructeur de recopie possédant un paramètre const...c'est quand même bien fait le C++

 

2) Et de plus je suis obligé de déclarer auto_ptr mutable, même si je ne le modifie pas dans une fonction const je veux dire, autrement
je me retrouve avec un problème de, auto_ptr: pas de constructeur de recopie de disponible, difficile de voir exactement où et pourquoi ça pêche

 

EDIT:
En faite ce bout de code permet de mieux comprendre ce qui se passe, j'ignorais la nécessité d'utiliser mutable dans
un cas comme celui-ci

Code :
  1. struct B
  2. {
  3. B(){}
  4. B(B& f){cout<<"copie";}
  5. };
  6. struct A
  7. {
  8. mutable B b; // mutable obligatoire
  9. A(){}
  10. A(const A& a):b(a.b){}
  11. };
  12. int main()
  13. {
  14. A a;
  15. A a2(a);
  16. system("pause" );
  17. }


Message édité par weblook$$ le 23-03-2009 à 02:11:42

---------------

Reply

Marsh Posté le 23-03-2009 à 08:07:06    

oops ok en faite je me tirais une balle dans le pied au niveau du constructeur par recopie... comme le disais Joel,un auto_ptr ne se copie pas...
 
  MaClasse(const MaClasse& m):
  m_(m.m_),
  ss_( std::auto_ptr<stringstream>(new stringstream()) )
 {
 }


Message édité par weblook$$ le 23-03-2009 à 11:51:35

---------------

Reply

Marsh Posté le 23-03-2009 à 08:15:41    

c'est pas tellement que ça se copie pas, c'est que de toutes façons, ça veut dire transférer le contenu.

Reply

Sujets relatifs:

Leave a Replay

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