C ++ - передача std :: ostream в функцию - PullRequest
3 голосов
/ 03 февраля 2010

Я подумал о маленькой встроенной функции отладки в C ++:

void inline debug( int debug_level, ostream& out ) {
    if ( debug_level <= verbosity ) {
        out.flush();
    }
    else {
        ostream tmp;
        tmp << out;
    }
}

Это пример того, как я хотел его использовать:

_debug( 7, cout << "Something something" << someint << endl );

Однако это не работает так, как я планировал - я хотел, чтобы оно печатало сообщение, только если уровень детализации выше или равен уровню отладки, переданному в функцию, но, похоже, он печатается каждый раз, независимо от уровня отладки, поэтому данные остаются в буфере Cout. Сейчас я думаю, что эта функция не самая лучшая идея, которая у меня была в последнее время, но все же я хочу знать, есть ли способ очистить буфер, связанный с cout, cerr и т. Д. Возможно ли заставить эту функцию работать должным образом?

Ответы [ 4 ]

6 голосов
/ 03 февраля 2010

Либо с помощью макроса, как показано выше, либо так:

struct nullstream : ostream {
    nullstream() : ostream(0) { }
};

ostream& dout(int debug_level, ostream& out = cerr) {
    static nullstream dummy;
    return debug_level <= verbosity ? dummy : out;
}

// …

dout(level) << "foo" << endl;
dout(level, cout) << "IMPORTANT" << endl;

(Использование endl также вызывает сброс, нет необходимости выполнять сброс вручную!)

2 голосов
/ 03 февраля 2010

Это всегда будет печатать сообщение, потому что параметры функции оцениваются до ввода тела функции.Вы можете получить эффект, который, я думаю, вам нужен, с помощью макроса, поскольку параметры макроса оцениваются только при их использовании:

#define DOUT( level, expr )   \
   if ( level >= verbosity )  {     \
      expr << endl;          \
  }

Используется:

 DOUT( 42, cout << "The value is " << something );

Если вы требовательнывы захотите обернуть это в цикл do / while - лично я никогда не буду беспокоиться об этом.

2 голосов
/ 03 февраля 2010

Я не уверен, что это можно сделать с помощью функций / шаблонов. Я знаю код с макросами (ваш лог-сообщение и поток разделены):

#define LOG(svrty, out, msg)\
do {\
  if (svrty >= debug_level) out << msg;\
} while(0)

Хотя это работает, меня интересуют лучшие решения. Обратите внимание, что вы должны позволить конфигурации и уровню отладки решать, куда вести журнал.

0 голосов
/ 03 февраля 2010

Настраивается ли время выполнения уровня отладки?
Если нет, вы можете использовать шаблоны и специализацию шаблонов:

template <int DebugLevel, int Verbosity>
ostream &debug(ostream &out);

template<>
ostream &debug<7, 5>(ostream &out) { /* do stuff */ }

Таким образом, если вы не хотите ничего выводить, просто верните фиктивный ostream, как предложил Конрад Рудольф.

...