Reputation: 6415
Can anyone suggest a way to have a null std::ostringstream
that avoids doing any work on the parameters passed to it with <<
?
There are two related posts here Implementing a no-op std::ostream and Printing to nowhere with ostream , so far the most promising solution is https://stackoverflow.com/a/760353/826203 , but while test it
int main() {
onullstream os;
os << 666;
// std::ostringstream & oss = os; // error C2440: 'initializing' : cannot convert from 'onullstream' to 'std::ostringstream &'
oss << "hello, world";
}
however, this could only be used like os<<666
, but could not be used as a std::ostringstream &
. any way out here?
Upvotes: 0
Views: 225
Reputation: 153840
The easiest way to create a non-operational stream is to actually not create a custom stream class but rather to disable an existing stream. For example, you can disable formatting to an std::ostream
by setting its stream buffer to null:
std::ostringstream out;
out.std::ostream::rdbuf(0);
// any attempt to write anything to out will fail.
If you need a stream which successfully fails to format data you can create a stream buffer which doesn't store any bytes and is always successful. However, when using this stream buffer the actually formatting will be performed:
struct nullbuf: std::streambuf {
std::streambuf::int_type overflow(std::streambuf::int_type c) {
return std::char_traits<char>::not_eof(c);
}
};
// ...
nullbuf buf;
std::ostringstream out;
out.std::ostream::rdbuf(&buf);
Note that I would also recommend not to have functions take a std::ostringstream
as arguments. Instead, any function which doesn't construct the stream should travel in terms of std::ostream&
. If your existing interfaces already take an std::ostringstream
you can create a a null stream by deriving from std::ostringstream
and setting the stream buffer appropriately:
class onullstream
: private virtual nullbuf
, public std::ostringstream {
public:
nullstring()
: std::ios(this)
, std::ostringstgream() {
this->std::ostream::rdbuf(this);
}
};
Upvotes: 3