21

重複の可能性:
no-op std::ostream の実装

c ++でNULLに相当するストリームはありますか? ユーザーが内部をどこかに出力したい場合はストリームを受け取る関数を書きたいのですが、そうでない場合、出力は偽の場所に行きます

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

やるdata()かを選べるようになりたいdata(std::cout)

4

3 に答える 3

35

編集:@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...
}

さて、これはクールに見えますが、以下ははるかに短く、機能します。これは、のコンストラクターにnullポインターが提供された場合、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()-sbがnullポインターでない場合はgoodbit、それ以外の場合はbadbit。

badbitが設定されている場合はどうなり27.6.2.6 [lib.ostream.unformatted]ますか?

フォーマットされていない各出力関数は、クラスのオブジェクトを作成することによって実行を開始しますsentry。このオブジェクトがtrueを返す場合、bool型の値に変換している間、関数は要求された出力を生成しようとします。

これは、sentryがfalseの場合、そうではないことを意味します。から取得した、へのsentry変換方法は次のとおりです。bool27.6.2.3 [lib.ostream::sentry] p3 & p5

3)準備が完了した後、がos.good()そうでない場合は、。trueok_ == trueok_ == false

5)operator bool();
効果:ok_を返します。

(タイプok_のメンバーです。)ostream::sentrybool


これらの引用符は、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
于 2011-06-05T04:20:31.597 に答える
1

Linux ファイル /dev/null は、探しているようなブラック ホールです。Windows には NUL: というデバイスがあります。そのファイルを開こうとしたことはありませんが、コマンドラインから使用したことはあります

于 2011-06-05T05:35:08.490 に答える
-1

ostream(NULL、false)を試すことができます。最初の入力はターゲット出力であり、2番目の入力の正確な意味はわかりませんが、コードをトレースした後、ostreamに書き込む場所がないため、呼び出しoperator <<はostreamによって無視されます. つまり、最初の呼び出し状態が悪い状態に変化し、その後はストリーム状態のために常に入力データを無視しているため、次のコードを使用できます。

void data(std::ostream & stream = ostream(NULL,false)){
    stream << "DATA" ;
}
于 2011-06-05T06:28:04.703 に答える