Your manipulator should be declared as a function that takes only one argument of type ostream& . However, if you make it a member function, you know that the implicit this argument is passed to the function.
Thus, you should rather declare your manipulator as a free, non-member function, making it a friend your class so that it can access its private ib member:
class IndentStream : public ostream { public: IndentStream(ostream &os) : ib(os.rdbuf()), ostream(&ib){}; ostream& indent(ostream& stream) { ib.indent(); return stream; } friend ostream& deindent(ostream& stream); // ^^^^^^ private: indentbuf ib; }; ostream& deindent(ostream& stream) { IndentStream* pIndentStream = dynamic_cast<IndentStream*>(&stream); if (pIndentStream != nullptr) { pIndentStream->ib.deindent(); } return stream; } int main() { IndentStream is(cout); is << "31 hexadecimal: " << hex << 31 << endl; is << "31 hexadecimal: " << hex << 31 << deindent << endl; is << "31 hexadecimal: " << hex << 31 << endl; return 0; }
Alternatively, if you really want your function to be a member, you can make it static:
class IndentStream : public ostream { public: IndentStream(ostream &os) : ib(os.rdbuf()), ostream(&ib){}; ostream& indent(ostream& stream) { ib.indent(); return stream; } static ostream& deindent(ostream& stream) { IndentStream* pIndentStream = dynamic_cast<IndentStream*>(&stream); if (pIndentStream != nullptr) { pIndentStream->ib.deindent(); } return stream; } private: indentbuf ib; };
However, this will force you to use a qualified name to refer to it:
int main() { IndentStream is(cout); is << "31 hexadecimal: " << hex << 31 << endl; is << "31 hexadecimal: " << hex << 31 << IndentStream::deindent << endl;
source share