Why I can't just create an "empty" stream for my output like this
std::ostream out;
?
This rows is apparently illegal with both clang 3.4 and gcc 4.8.1 under linux with libstdc++, I really don't get why, I mean why I can't just create a stream out of nowhere and use it like I want to ? notice that std::ofstream out; is 100% ok instead. I just don't get the logic behind this.
This is even stranger if you consider that after the creation I can just use this buffer and share a common buffer with other buffers with copyfmt so there is no real need for my std::ostream to be initialized to something right from the creation of the object to be useful.
Please don't deviate from this, I don't need stringstreams, I need ios streams because of what I have to do and because of the methods and the properties that they are offering.
I'll admit that I don't understand it either. I can't find any
default constructor at all for std::istream, and I would think
you would want one if you want to create a bidirectional stream,
because of the strange way std::ios_base works: the
constructor does not initialize anything, but the derived
class must call std::ios_base::init explicitly in its
constructor. When multiple inheritance is involved (i.e.
bidirectional IO, where the class derives from both
std::istream and std::ostream), I would expect only the most
derived class to call std::ios_base::init. (In
std::iostream, std::ios_base::init will be called twice.)
In fact, before looking it up in the standard, I was about to
answer that the default constructor was protected, because it
didn't call std::ios_base::init, and using it directly, rather
than in a derived class, would result in an uninitialized
stream.
Anyhow, your immediate problem has a simple solution:
std::ostream out( NULL );
Also: the function you need to set up its sink later is the
non-const version of rdbuf(), not copyfmt(). rdbuf() is
used to read and to set the pointer to the streambuf,
copyfmt() copies the formatting flags, but does not touch
the pointer to streambuf.
So you can do things like:
std::ostream out( NULL );
// ...
std::filebuf fileBuffer;
if ( filenameGiven ) {
fileBuffer.open( filename.c_str(), std::ios_base::out );
}
if ( fileIsOpen() ) {
out.rdbuf( &fileBuffer );
} else {
out.rdbuf( std::cout.rdbuf() );
}
(I do this a lot. In fact, I thought that it was the usual
idiom when you didn't know up front whether to output to a file
or to std::cout.)
EDIT:
And yet another correction: the non-const version of rdbuf calls clear(),
so you don't have to. (I knew I'd done this without calling clear(), but
when I saw that init set badbit...)
Anyhow: the summary is: it's usually preferrable to pass a pointer to a valid
streambuf to the constructor of std::ostream, but if you can't, it's
perfectly valid to pass a null pointer, and set a valid pointer later using
rdbuf(). And the answers which say otherwise are simply wrong.
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