Extending C++ ostream
c++, iostream
Solution
Single-character output is handled by `overflow`. Here's how you might implement `overflow` in terms of `xsputn` if `xsputn` does the actual outputting:
int_type overflow(int_type c = traits_type::eof())
{
if (c == traits_type::eof())
return traits_type::eof();
else
{
char_type ch = traits_type::to_char_type(c);
return xsputn(&ch, 1) == 1 ? c : traits_type::eof();
}
}
Problem
I'm trying to learn more about the workings of the C++ I/O stream library by extending `std::streambuf`. As a learning experiment, my goal is to simply create a custom stream which directs all output to `std::cerr`. It seems simple enough: ``` #include <iostream> using namespace std; class my_ostreambuf : public std::streambuf { public: protected: std::streamsize xsputn(const char * s, std::streamsize n) { std::cerr << "Redirecting to cerr: " << s << std::endl; return n; } }; int main() { my_ostreambuf buf; std::ostream os(&buf); os << "TEST"; } ``` This seems to work, since it prints `Redirecting to cerr: TEST`. The problem is that it doesn't work when a single character (as opposed to a string) is inserted into the stream via `std::ostream::sputc`. For example: ``` int main() { my_ostreambuf buf; std::ostream os(&buf); os << "ABC"; // works std::string s("TEST"); std::copy(s.begin(), s.end(), std::ostreambuf_iterator<char>(os)); // DOESN'T WORK } ``` The problem I guess is that `xsputn` doesn't handle single character insertion. (I guess `sputc` doesn't call `xsputn` internally?) But, looking over the list of virtual protected functions in `std::streambuf`, I don't see any function I'm supposed to override that handles single character insertion. So, how can I accomplish this?