web-dev-qa-db-ja.com

標準の何もしない出力ストリーム

基本的に何もしないostreamインスタンスを作成する方法はありますか?

例えば ​​:

std::ostream dummyStream(...);
dummyStream << "Nothing will be printed";

私はostringstreamを作成することもできましたが、データはバッファーに入れられます(そして、実際には何も作成したくないので、無駄なオーバーヘッドが追加されます)。

何か案が ?

[編集]これが見つかりました 関連する質問 これは私のニーズに合います。ただし、標準のC++でvalid(no badbit)出力ストリームを作成する方法を示す答えがあると便利だと思います。

41
Maël Nison

カスタムstreambufが必要です。

class NullBuffer : public std::streambuf
{
public:
  int overflow(int c) { return c; }
};

その後、このバッファを任意のostreamクラスで使用できます

NullBuffer null_buffer;
std::ostream null_stream(&null_buffer);
null_stream << "Nothing will be printed";

streambuf::overflowは、バッファーがストリームの実際の宛先にデータを出力する必要があるときに呼び出される関数です。上記のNullBufferクラスは、オーバーフローが呼び出されても何も実行しないため、それを使用するストリームは出力を生成しません。

66
john

これがログ出力を無効にすることである場合でも、dummyStreamによって引数が評価されます。ロギングが無効になっているときの影響を最小限にしたい場合は、次のような条件に依存できます。

#define debugStream \
    if (debug_disabled) {} \
    else std::cerr

したがって、次のようなコードがある場合:

debugStream << "debugging output: " << foo() << std::endl;

debug_disabledがtrueの場合、引数は評価されません。

32
jxh

新しいストリームクラスの基本メソッドは次のとおりです。

  1. std::streambufからクラスを派生させる;
  2. そのクラスの仮想関数をオーバーライドします。これは、実際の作業が行われる場所です。あなたの場合、空の実装で十分です。
  3. std::ostreamからクラスを1つのメンバーであるstreambufクラスを使って派生させます。
  4. Streamclassのコンストラクターは、そのメンバーへのポインターをstd :: ostreamの基本コンストラクターに転送する必要があります。

ただし、フォーマットの手順は不要です。

うまくいけば、これによりいくつかの指針が得られます。これを完全な答えに展開する時間はありません。申し訳ありません。

更新:詳細は john's answer を参照してください。

3
Sjoerd

デバッガーのオーバーヘッドが心配な場合は、非常に単純なコードを記述して、コンパイル時にデバッグメッセージを無効にすることができます。これは私のc ++プログラムに使用するものです。

#include <iostream>
#define DEBUGGING // Define this in your config.h or not.
#ifdef DEBUGGING
/*
 * replace std::cout with your stream , you don't need to
 * worry about the context since macros are simply search
 * and replace on compilation.
 */
#define LOG_START std::cout <<
#define LOG_REDIR <<
#define LOG_END   << std::endl;
#else
#define LOG_START (void)
#define LOG_REDIR ;(void)
#define LOG_END   ;
#endif // DEBUGGING

int main(){
LOG_START "This is a log message " LOG_REDIR "Still a log message." LOG_END;
return 0;
}

プロジェクトを作成するときに、ユーザーがロギングを無効にしたいかどうかを確認します。無効にしたい場合は、DEBUGGINGマクロまたは確認することを選択したマクロの定義を解除します。

これで、コードはコンパイラーによって最適化されます。何かが無効にされた場合、結果のバイナリーには(ほとんどの場合)含まれないため、バイナリー生成の準備が整います。

0
antonyjr