Edit: Taken from @Johannes Schaub - litb's mail here with slight modifications:
template<typename Ch, typename Traits = std::char_traits<Ch> >
struct basic_nullbuf : std::basic_streambuf<Ch, Traits> {
typedef std::basic_streambuf<Ch, Traits> base_type;
typedef typename base_type::int_type int_type;
typedef typename base_type::traits_type traits_type;
virtual int_type overflow(int_type c) {
return traits_type::not_eof(c);
}
};
// convenient typedefs
typedef basic_nullbuf<char> nullbuf;
typedef basic_nullbuf<wchar_t> wnullbuf;
// buffers and streams
// in some .h
extern std::ostream cnull;
extern std::wostream wcnull;
// in a concrete .cpp
nullbuf null_obj;
wnullbuf wnull_obj;
std::ostream cnull(&null_obj);
std::wostream wcnull(&wnull_obj);
Use those:
void data(std::ostream& stream = cnull){
// whatever...
}
Now, this looks cool and all, but the following is way shorter and works, because if a null pointer is provided to the constructor of ostream
, it automatically sets the badbit and silently ignores any writes:
// in .h
extern std::ostream cnull;
extern std::wostream wcnull;
// in .cpp
std::ostream cnull(0);
std::wostream wcnull(0);
The standard guarantees this works, beginning from 27.6.2.2 [lib.ostream.cons] p1
which describes the constructor of ostream
that takes a pointer to a streambuf
:
Effects: Constructs an object of class basic_ostream
, assigning initial values to the base class by calling basic_ios<charT,traits>::init(sb)
.
The relevant function from basic_ios
, 27.4.4.1 [lib.basic.ios.cons] p3
:
void init(basic_streambuf<charT,traits>* sb);
Postconditions: The postconditions of this function are indicated in Table 89:
The important row from Table 89:
rdstate() -- goodbit if sb is not a null pointer, otherwise badbit.
What happens if the badbit
is set is described under 27.6.2.6 [lib.ostream.unformatted]
:
Each unformatted output function begins execution by constructing an object of class sentry
. If this object returns true, while converting to a value of type bool, the function endeavors to generate the requested output.
This implies that, in case the sentry
is false, it does not. Here is how the sentry
converts to bool
, taken from 27.6.2.3 [lib.ostream::sentry] p3 & p5
:
3) If, after any preparation is completed, os.good()
is true
, ok_ == true
otherwise, ok_ == false
.
5) operator bool();
Effects: Returns ok_.
(ok_
is a member of ostream::sentry
of type bool
.)
Note that these quotes are still present in C++11, just in different places. In order of appearance in this answer:
27.6.2.2 [lib.ostream.cons] p1
=> 27.7.3.2 [ostream.cons] p1
27.4.4.1 [lib.basic.ios.cons] p3
=> 27.5.5.2 [basic.ios.cons]
- Table 89 => Table 128
27.6.2.6 [lib.ostream.unformatted]
=> 27.7.3.7 [ostream.unformatted] p1
27.6.2.3 [lib.ostream::sentry] p3 & p5
=> 27.7.3.4 [ostream::sentry] p4 & p5
"but destroyed if not"
mean? Why don't you write pseudocode to clarify your question? – Bedwell