I've been writing a custom std::streambuf
as part of a logging system. However, I'm having problems with the first piece of output from a stream not being formatted correctly.
Here's a reduced test-case that doesn't use any custom streambuf
or ostream
classes:
#include <iostream>
int main()
{
std::streambuf *coutbuf = std::cout.rdbuf();
std::ostream(coutbuf) << "test" << ": writing to cout using a separate ostream." << std::endl;
return 0;
}
Compiling this using g++:
$ g++ --version
g++ (Ubuntu 4.4.1-4ubuntu8) 4.4.1
$ g++ -o fail reduced-case.cpp
$ ./fail
0x400c80: writing to cout using a separate ostream.
Note that the first string literal ("test") is being formatted as a generic pointer (the address of the string is output in hex), while the second string literal is formatted correctly.
The only thing I can think of is that it's invalid to directly use a newly constructed std::ostream
like that (ie, without putting it into a variable). If this is the case, I'd very much like to know what exactly makes it invalid (I assume it's nothing to do with iostreams specifically, but rather order-of-evaluation or interactions with constructors or something). If that's not the problem, then what is?
The problem is that you must not write to a temporary stream object. This:
std::ostream(coutbuf) << "blah";
doesn't work as expected, since the left-hand argument for operator<<()
is an rvalue. However, all the operators overloaded as a free function take a non-const reference to a stream as their left-hand argument:
std::ostream& operator<<(std::ostream&, ...);
Since rvalues do not bind to non-const references, they cannot be called.
I suspect that your std lib implementation implements <<
for const char*
as a free function and has thus to fall back to some <<
that's a member of std::ostream
. It seems in your implementation that's the one outputting any pointer as a void*
.
Bottom line: Don't attempt to write to temporary stream objects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With