Ответ 1
Изменить: взято из @Johannes Schaub - litb mail здесь с небольшими изменениями:
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
, он автоматически устанавливает badbit и молча игнорирует любые записи:
// 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() - goodbit, если sb не является нулевым указателем, иначе badbit.
Что произойдет, если параметр 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
.)
Обратите внимание, что эти цитаты все еще присутствуют на С++ 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