Правка: взято из письма @Johannes Schaub от litb здесь с небольшими изменениями:
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);
Используйте те:
void data(std::ostream& stream = cnull){
// whatever...
}
Теперь это выглядит круто и все такое, но следующее намного короче и работает, потому что если нулевой указатель предоставляется конструктору ostream
, он автоматически устанавливает плохой бит и молча игнорирует любые записи:
// in .h
extern std::ostream cnull;
extern std::wostream wcnull;
// in .cpp
std::ostream cnull(0);
std::wostream wcnull(0);
Стандарт гарантирует, что это работает, начиная с 27.6.2.2 [lib.ostream.cons] p1
, который описывает конструктор ostream
, принимающий указатель на streambuf
:
Эффекты: Создает объект класса basic_ostream
, присваивая начальные значения базовому классу путем вызова basic_ios<charT,traits>::init(sb)
.
Соответствующая функция из basic_ios
, 27.4.4.1 [lib.basic.ios.cons] p3
:
void init(basic_streambuf<charT,traits>* sb);
Постусловия: Постусловия этой функции указаны в таблице 89:
Важная строка из Таблицы 89:
rdstate() -- хороший бит, если sb не является нулевым указателем, иначе плохой бит.
Что произойдет, если установить badbit
, описано в разделе 27.6.2.6 [lib.ostream.unformatted]
:
Каждая неформатированная функция вывода начинает выполнение с создания объекта класса sentry
. Если этот объект возвращает true, при преобразовании в значение типа bool функция пытается сгенерировать запрошенный вывод.
Это означает, что в случае, если sentry
ложно, это не так. Вот как sentry
преобразуется в bool
, взятое из 27.6.2.3 [lib.ostream::sentry] p3 & p5
:
3) Если после завершения какой-либо подготовки os.good()
будет true
, ok_ == true
в противном случае ok_ == false
.
5) operator bool();
Эффекты: Возвращает ok_.
(ok_
является членом ostream::sentry
типа bool
.)
Обратите внимание, что эти кавычки все еще присутствуют в C++11, просто в других местах. В порядке появления в этом ответе:
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]
- Таблица 89 => Таблица 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
person
Xeo
schedule
05.06.2011
"but destroyed if not"
? Почему бы вам не написать псевдокод, чтобы прояснить свой вопрос? - person Nawaz   schedule 05.06.2011