Schreiben eines Manipulators für eine benutzerdefinierte Stream-Klasse

Ich habe eine benutzerdefinierte Stream-Klasse geschrieben, die eingerückten Text ausgibt und über Manipulatoren verfügt, mit denen die Einrückungsstufe geändert werden kann. Die gesamte Einrückungsarbeit wird in einer benutzerdefinierten Stream-Pufferklasse implementiert, die von der Stream-Klasse verwendet wird. Der Puffer funktioniert (d. H. Der Text ist in der Ausgabe eingerückt), aber ich kann meine Manipulatoren nicht zum Arbeiten bringen. Ich habe an vielen Stellen gelesen, wie ostream (den meine Klasse erweitert) den Operator überlastet.

ostream& ostream::operator << ( ostream& (*op)(ostream&))

{
    // call the function passed as parameter with this stream as the argument
    return (*op)(*this);
}

Das heißt, es kann eine Funktion als Parameter aufnehmen. Warum werden meine Stream-Funktionen "Einrücken" oder "Nicht-Einrücken" nicht erkannt? Ich bin mir sicher, dass ich den Operator << überladen muss, aber sollte ich das nicht tun müssen? Siehe unten für meinen Code:

#include <iostream>
#include <streambuf>
#include <locale>
#include <cstdio>

using namespace std;

class indentbuf: public streambuf {

public:

    indentbuf(streambuf* sbuf): m_sbuf(sbuf), m_indent(4), m_need(true) {}

    int indent() const { return m_indent; }
    void indent() { m_indent+=4; }
    void deindent() { if(m_indent >= 4) m_indent-= 4; }

protected:

    virtual int_type overflow(int_type c) {

        if (traits_type::eq_int_type(c, traits_type::eof()))

            return m_sbuf->sputc(c);

        if (m_need)
        {
            fill_n(ostreambuf_iterator<char>(m_sbuf), m_indent, ' ');
            m_need = false;
        }

        if (traits_type::eq_int_type(m_sbuf->sputc(c), traits_type::eof()))

            return traits_type::eof();

        if (traits_type::eq_int_type(c, traits_type::to_char_type('\n')))

            m_need = true;

        return traits_type::not_eof(c);
    }

    streambuf* m_sbuf;
    int m_indent;
    bool m_need;
};

class IndentStream : public ostream {
public:
    IndentStream(ostream &os) : ib(os.rdbuf()), ostream(&ib){};

    ostream& indent(ostream& stream) {
        ib.indent();
        return stream;
    }

   ostream& deindent(ostream& stream) {
        ib.deindent();
        return stream;
    }

private:
    indentbuf ib;
};

int main()
{
    IndentStream is(cout);
    is << "31 hexadecimal: " << hex << 31 << endl;
    is << "31 hexadecimal: " << hex << 31 << endl;
    is << "31 hexadecimal: " << hex << 31 << deindent << endl;
    return 0;
}

Vielen Dank!

Antworten auf die Frage(1)

Ihre Antwort auf die Frage