重複の可能性:
no-op std::ostream の実装
c ++でNULLに相当するストリームはありますか? ユーザーが内部をどこかに出力したい場合はストリームを受け取る関数を書きたいのですが、そうでない場合、出力は偽の場所に行きます
void data(std::stream & stream = fake_stream){
stream << "DATA" ;
}
やるdata()
かを選べるようになりたいdata(std::cout)
重複の可能性:
no-op std::ostream の実装
c ++でNULLに相当するストリームはありますか? ユーザーが内部をどこかに出力したい場合はストリームを受け取る関数を書きたいのですが、そうでない場合、出力は偽の場所に行きます
void data(std::stream & stream = fake_stream){
stream << "DATA" ;
}
やるdata()
かを選べるようになりたいdata(std::cout)
編集:@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
変換方法は次のとおりです。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
これらの引用符は、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]
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
Linux ファイル /dev/null は、探しているようなブラック ホールです。Windows には NUL: というデバイスがあります。そのファイルを開こうとしたことはありませんが、コマンドラインから使用したことはあります
ostream(NULL、false)を試すことができます。最初の入力はターゲット出力であり、2番目の入力の正確な意味はわかりませんが、コードをトレースした後、ostreamに書き込む場所がないため、呼び出しoperator <<
はostreamによって無視されます. つまり、最初の呼び出し状態が悪い状態に変化し、その後はストリーム状態のために常に入力データを無視しているため、次のコードを使用できます。
void data(std::ostream & stream = ostream(NULL,false)){
stream << "DATA" ;
}