cout mit ANSI control sequenzen, << overloading



  • Ich probiere mich gerade mit ANSI Kontroll Sequenzen, zum Beispiel:
    "\33[Zeile;SpalteH"
    Das geht soweit auch, allerdings hätte ich gerne die Möglichkeit diese als so eine Art Modifikator in die cout streams einzufügen, also z.B. folgendes zu machen:

    cout << setxy(10,20) << "text" << endl;
    

    setxy soll ein temporäres Objekt sein, welches den entsprechenden Kontroll String in den Stream einfügt.

    Mein Code bisher:

    class setxy{
    private: string escseq;
    public:
        setxy(size_t x, size_t y);
        friend ostream& operator <<(ostream& os, setxy &sxy);
    };
    
    ostream &operator <<(ostream& os, setxy &sxy){
        return os << sxy.escseq;
    }
    
    setxy::setxy(size_t x, size_t y){
        stringstream strs;
        strs << "\33[" << y+1 << ';' << x+1 << 'H' << endl;
        getline(strs, escseq);
    }
    
    int main()
    {
        setxy sxy(10,5);
        cout << sxy << "works" << endl;
        cout << setxy(1,2) << "works not" << endl;
        return 0;
    }
    

    Was mich hier ein bisschen nervt, ist dass man das setxy Objekt offensichtlich nicht temporär erzeugen kann und man den Umweg über eine manuelle Erstellung eines Objektes wählen muss.
    Gibt es da eine Möglichkeit, die ich nicht sehe?
    Gerne würde ich setxy auch als Ableitung einer übergeordneten Klasse
    ansi definieren, die weitere Umsetzungen der Kontroll Sequenzen beinhaltet.
    Also z.B.:

    class ansi{
    private:
       string escseq;
    public:
       ansi::ansi(void){};
       /*common methods*/
    }
    
    class setxy:ansi{
       /*special methods*/
    }
    
    class cls:ansi{
    }
    ...
    


  • Wenn du deinen operator<< so umbaust, dass er deine Klasse als const Reference nimmt, dann funktioniert es. Nur const References und Rvalue References binden an temporäre Werte.


  • Mod

    const-Correctness beachten!

    ostream& operator <<(ostream& os, const setxy &sxy);
    

    Dann geht es wie gewollt.

    Weiterhin noch der Tipp, dass deine Zahlen->Stringstream->String Verkettung ziemlich umständlich ist. Gib der Klasse doch einfach ein Koordinatenpaar als Member und schreib dann die Kontrollsequenz direkt in die Ausgabe!

    class setxy{
    private: size_t x,y;
    public:
      setxy(size_t x, size_t y): x(x), y(y) {}
      friend ostream& operator <<(ostream& os, const setxy &sxy)
      {
        return os << "\33[" << sxy.y+1 << ';' << sxy.x+1 << 'H' << endl;
      }
    };
    

    Wobei das natürlich hinderlich ist bei deinem Vorhaben, alles von einer übergeordneten Klasse abzuleiten. Aber ich sehe überhaupt keinen Grund, etwas von einer übergeordneten Klasse abzuleiten, da es überhaupt keine Gemeinsamkeiten gäbe. Die Gemeinsamkeit wäre ja dieses unnötige Stringstream/String Gefummel, aber das kann man sich schließlich besser ganz sparen.



  • Cool, danke!


Anmelden zum Antworten