athos
athos

Reputation: 6415

Implementing a no-op std::ostringstream that can be accepted as a std::ostringstream reference

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

Answers (1)

Dietmar K&#252;hl
Dietmar K&#252;hl

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

Related Questions