Überladen von "<<" bzw. "[]" Operatoren



  • Hallo, ich arbeite gerade an einer Vektorklasse und bei folgender Methode erhalte ich eine Fehlermeldung des Kompilers:

    std::ostream& operator<<(std::ofstream& stream,Vek3 vektor)
    {
        return stream << vektor[0] << std::endl;
    }
    

    Die Fehlermeldung:
    "no match for 'operator<<' in 'stream << vektor.Vek3::operator[](0u)'
    D:\C++\Lulz\src\Vek3.cpp:58: note: candidates are: std::ostream& operator<<(std::ofstream&, Vek3)
    include/Bruch.h:27: note: std::ostream& operator<<(std::ostream&, Bruch)
    "

    Die Elemente des Vektors bestehen aus einer eigenen Bruchklasse die ich als vector gespeichert habe.

    In der Vektorklasse sieht die Überladung des [] Operators wie folgt aus:

    Bruch& Vek3::operator[](unsigned int i)
    {
        if(i<data.size())
        return data[i];
    else data[0];
    }
    

    Den elseteil gerade mal ignorieren, weiß noch nicht wie ich den Fehlerfall behandle.

    Ferner hier die Überladung des "<<" Operators meiner Bruchklasse:

    std::ostream& operator<<(std::ostream& Stream, Bruch B)
    {
        return Stream << B.Z() << "/" << B.N();
    }
    

    Die Bruchklasse habe ich separat getestet und sollte funktionieren(Hat zumindest richtig funktioniert).

    Ich weiß nicht wieso der Streamoperator uneindeutig sein soll:

    das vektor[0] liefert doch eine Referenz auf ein Objekt des Typs Bruch welche eine ordentliche Überladung für den Streamoperator besitzt.

    Wieso meckert das Compiler?

    Vielen Dank 🙂


  • Mod

    Du hast einmal ofstream statt ostream geschrieben. Ein ofstream ist zwar ein ostream, aber nicht umgekehrt, daher passt das nicht zusammen.*

    Den Fehlermeldungen sehe ich an, dass du vermutlich einen GCC-artigen Compiler benutzt. Da empfehle ich, eine der neueren Versionen zu benutzen, ab mindestens 4.6 (4.5 habe ich übersprungen und mittlerweile gibt es sogar 4.7 (und 4.8 beta)) wurden die Fehlermeldungen gründlich überarbeitet und sind nun sehr sehr hilfreich. Da ergibt dein Programm:

    In function ‘std::ostream& operator<<(std::ofstream&, Vek3)’:
    error: no match for ‘operator<<’ in ‘stream << vektor.Vek3::operator[](0u)’
    note: candidates are:
    note: std::ostream& operator<<(std::ostream&, Bruch)
    note:   no known conversion for argument 1 from ‘std::ofstream {aka std::basic_ofstream<char>}’ to ‘std::ostream& {aka std::basic_ostream<char>&}’
    note: std::ostream& operator<<(std::ofstream&, Vek3)
    note:   no known conversion for argument 2 from ‘Bruch’ to ‘Vek3’
    ...und noch ein paar mehr Kandidaten...
    

    Das ist doch eine ziemlich eindeutige Erklärung und man sieht sofort den Fehler.

    P.S.: Außerdem: const-Correctness! Mal kundig machen, was das bedeutet und benutzen. Ist zwar zuerst etwas nervig, nützt aber mittelfristig sehr beim Schreiben korrekter Programme.

    *: Bei genauerer Betrachtung passt es hier doch zusammen, da du einen ofstream als Argument benutzt, wo ein ostream& erwartet wird. Also einen ofstream an eine ostream& binden willst**, was schon geht. Dafür müssen dem Compiler aber die Verwandschaftsbeziehungen bekannt sein. Das sind sie aber nicht, da du (zu deinem Glüçk) den Header fstream nicht eingebunden hast. Falls du das doch getan hättest, dann hätte es jedoch gekracht, sobald du versucht hättest, einen Vek3 in einen Nicht-ofstream zu schreiben.

    **: Oder eher nicht willst, da es ein Schreibfehler sein dürfte.



  • Oh, das da habe ich den Wald vor läuter Bäumen gesehen, ich habe zig mal draufgeschaut und das überhaupt nicht bemerkt, danke sehr.

    Ja, jetzt wo du mich drauf hingewiesen hast ist es ja klar, aber ich hab mir die Fehlermeldung angeschaut und immer ostream gelesen einfach weil ich nicht an nen Tippfehler gedacht habe.


  • Mod

    Namenloser324 schrieb:

    Ja, jetzt wo du mich drauf hingewiesen hast ist es ja klar, aber ich hab mir die Fehlermeldung angeschaut und immer ostream gelesen einfach weil ich nicht an nen Tippfehler gedacht habe.

    Merke: Der Compiler hat immer Recht 😃 . Ich habe auch heute 10 Minuten an einem ganz ähnlichem Problem gesessen, wo ich bei exakt dieser Fehlermeldung den kleinen Schreibfehler nicht gesehen habe und stattdessen an einen komplizierten Fehler bei der Auflösung von überladenen Templates gedacht habe. Erst als ich es nicht im Minimalbeispiel reproduzieren konnte, habe ich nochmal genau hingeguckt.

    Ich habe dir oben übrigens nochmal eine etwas genauere Erklärung reineditiert, die erste war nicht 100% korrekt.


Anmelden zum Antworten