Klasse: Stream-Operator überladen



  • Ich bekomme das mit der Syntax gerade nicht auf die Reihe, gewünscht ist folgendes:

    MyClass a;
    a << "Text";
    a << 28;
    

    Intern besitzt a einen ofstream, in den soll einfach alles reingeschoben werden.
    Hab das jetzt so gelöst (ist das korrekt so?):

    template<class T>
    	  std::ofstream& operator << (T& t) {
    		  myFile << t;
    		  return myFile ;
    	  }
    


  • const T& t



  • class MyClass
    {
    private:
    	ofstream file;
    public:
    	template<class T>
        std::ofstream& operator<<(const T& t)
    	{
    		return file;
    	}
    };
    
    int main()
    {
    	MyClass a;
    	a << "Text";
    	a << 28;
    }
    

    bind literals to const-ref.



  • out, fehlt da nicht was?



  • Welchen Compiler/IDE nutzt du?

    Folgendes kompiliert einwandfrei unter Windows mit VC 2010 perfekt:

    #include <fstream>
    
    class MyClass
    {
    private:
        std::ofstream file;
    public:
        template<class T>
        std::ofstream& operator<<(const T& t)
        {
            return file;
        }
    };
    
    int main()
    {
        MyClass a;
        a << "Text";
        a << 28 << "l";
    }
    


  • Nein, ich meinte vom Sinn her.
    Ausgabe ohne Ausgabe ist irgendwie sinnfrei.

    Edit: Übrigens finde ich es blöd, dass nach der ersten Ausgabe ein anderer Operator aufgerufen wird. Die operator Funktion sollte besser MyClass& zurückliefern.



  • Was spricht gegen

    operator std::ostream&() { return file; }
    

    ?



  • Das, was immer gegen operator T spricht.



  • Nathan schrieb:

    Nein, ich meinte vom Sinn her.
    Ausgabe ohne Ausgabe ist irgendwie sinnfrei.

    Edit: Übrigens finde ich es blöd, dass nach der ersten Ausgabe ein anderer Operator aufgerufen wird. Die operator Funktion sollte besser MyClass& zurückliefern.

    Ein std::ofstream steht für eine Datei. Da erfolgt keine sichtbare Ausgabe.

    Wenn man MyClass& zurückgibt, dann hätte man ja nach jedem Operatoraufruf eine weitere Indirektion. Außerdem implementiert std::ofstream schon alles, also kann man auch an std::ofstream die weitere Verarbeitung abgeben.


  • Mod

    opi schrieb:

    Was spricht gegen

    operator std::ostream&() { return file; }
    

    ?

    Das macht nicht das gesuchte, dafür aber jede Menge anderes, was man nicht will.

    class MyClass
    {
      std::fstream file;
    public:
      operator std::ostream&() { return file; }
    };
    
    void bar(std::ostream& o);
    
    int main()
    {
      MyClass foo;
      foo << "Blah!"; // Geht nicht
      bar(foo);       // Geht! Gewollt?
    }
    

  • Mod

    SeppJ schrieb:

    foo << "Blah!"; // Geht nicht
    

    Das ließe sich sogar noch per using-Deklaration oder -Direktive reparieren. Spätestens bei

    foo << 42;
    

    ist allerdings nichts mehr zu machen.



  • ghjghjgh schrieb:

    Wenn man MyClass& zurückgibt, dann hätte man ja nach jedem Operatoraufruf eine weitere Indirektion. Außerdem implementiert std::ofstream schon alles, also kann man auch an std::ofstream die weitere Verarbeitung abgeben.

    Die Indirektion wird sowieso wegoptimiert. Dafür ist soetwas nicht möglich:

    class Foo
    {
    private:
         std::ostream& _o;
    
    public:
         template<typename T>
         Foo& operator<<(T const& v)
         {
             _o << v;
             return *this;
         }
    
         void complete();
    };
    
    ...
    
    Foo foo;
    (foo << 12.0f << "abc" << 12).complete();
    

    Außerdem kann der std::ostream ein Implementierungsdetail sein, das man nicht umbedingt nach außen tragen möchte.



  • Ethon schrieb:

    _o << v;
    

    Und das hier meinte ich mit "da fehlt was".


Log in to reply