Подтвердить что ты не робот

Независимость от платформы /dev/null в С++

Возможный дубликат:
Внедрение no-op std:: ostream

Есть ли эквивалент потока NULL в С++? Я хочу написать функцию, которая принимает поток, если пользователь хочет, чтобы внутренняя выведенная была где-то, но если нет, то выход идет в какое-то поддельное место

void data(std::stream & stream = fake_stream){
    stream << "DATA" ;
}

Я хочу иметь возможность делать data() или data(std::cout)

4b9b3361

Ответ 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

Ответ 2

Файл Linux/dev/null - черная дыра, которую вы ищете. В Windows есть устройство под названием NUL:. Я никогда не пытался открыть этот файл, но я использовал его из командной строки

Ответ 3

вы можете попробовать ostream (NULL, false), первый вход - целевой вывод, и я не знаю, что означает второе значение ввода, но после кода отслеживания кажется, что ostream не имеет места для записи, вызывая operator << просто игнорируется ostream. Я имею в виду, что в первом состоянии вызова изменяется на плохое, и после этого он всегда игнорирует входные данные из-за состояния потока, поэтому вы можете использовать следующий код:

void data(std::ostream & stream = ostream(NULL,false)){
    stream << "DATA" ;
}