Is there a way to extract iostate
(goodbit
,badbit
, failbit
) or other means of error state of a std::ostream
when I access this std::ostream
through a std::osyncstream
.
I would like to detect whether an output stream operation has succeeded or if the output stream is in an error state.
When using ostream
directly I could use fail()
, good()
and bad()
methods to determine the state of the stream. Consider a situation like this:
std::ofstream logFile("file1.txt");
std::ostream oStream(logFile.rdbuf());
{
std::ofstream logFile2("file2.txt");
oStream.rdbuf(logFile2.rdbuf());
}
std::cout << "oStream.fail(): " << oStream.fail() << "\n";
std::cout << "oStream.good(): " << oStream.good() << "\n";
std::cout << "oStream.bad(): " << oStream.bad() << "\n";
oStream << "This is probably UB because used streambuf is gone" << std::endl;
std::cout << "oStream.fail(): " << oStream.fail() << "\n";
std::cout << "oStream.good(): " << oStream.good() << "\n";
std::cout << "oStream.bad(): " << oStream.bad() << "\n";
However once I wrap the ostream
inside osyncstream
, I do not manage to get the stream state anymore. The goodbit
stays true
and failbit
/badbit
stay false for both the ostream
as well as the osyncstream
object, even though I would expect otherwise.
std::ofstream logFile("file1.txt");
std::ostream oStream(logFile.rdbuf());
{
std::ofstream logFile2("file2.txt");
oStream.rdbuf(logFile2.rdbuf());
}
std::osyncstream osyncStream(oStream);
std::cout << "oStream.fail(): " << oStream.fail() << "\n";
std::cout << "oStream.good(): " << oStream.good() << "\n";
std::cout << "oStream.bad(): " << oStream.bad() << "\n";
std::cout << "osyncStream.fail(): " << oStream.fail() << "\n";
std::cout << "osyncStream.good(): " << oStream.good() << "\n";
std::cout << "osyncStream.bad(): " << oStream.bad() << "\n";
osyncStream << "This is probably UB because used streambuf is gone" << std::endl;
std::cout << "oStream.fail(): " << oStream.fail() << "\n";
std::cout << "oStream.good(): " << oStream.good() << "\n";
std::cout << "oStream.bad(): " << oStream.bad() << "\n";
std::cout << "osyncStream.fail(): " << oStream.fail() << "\n";
std::cout << "osyncStream.good(): " << oStream.good() << "\n";
std::cout << "osyncStream.bad(): " << oStream.bad() << "\n";
Or maybe my whole approach to checking for error state of ostream
s is not correct. What I want to achieve in the end is to detect if a caller provides an ostream
to my class which goes out of scope while my class is still using it. As of today my class is either holding a std::reference_wrapper
to the external ostream
or using the underlying streambuf
as described in this anwser.
There is no standardized way to extract or observe the error state from a std::osyncstream
, because it's designed in such a way so that it buffers output for synchronized, thread-safe writes, while not exposing the underlying stream's state in the same way that a raw std::ostream
does.