5

私はstd::streambufロギングシステムの一部としてカスタムを書いてきました。ただし、ストリームからの最初の出力が正しくフォーマットされていないという問題があります。

streambufこれは、カスタムやostreamクラスを使用しない縮小されたテストケースです。

#include <iostream>

int main()
{
    std::streambuf *coutbuf = std::cout.rdbuf();
    std::ostream(coutbuf) << "test" << ": writing to cout using a separate ostream." << std::endl;
    return 0;
}

g ++を使用してこれをコンパイルします:

$ g++ --version
g++ (Ubuntu 4.4.1-4ubuntu8) 4.4.1

$ g++ -o fail reduced-case.cpp

$ ./fail
0x400c80: writing to cout using a separate ostream.

最初の文字列リテラル( "test")は汎用ポインターとしてフォーマットされています(文字列のアドレスは16進数で出力されます)が、2番目の文字列リテラルは正しくフォーマットされていることに注意してください。

私が考えることができる唯一のことは、そのstd::ostreamように新しく構築されたものを直接使用することは無効であるということです(つまり、それを変数に入れずに)。この場合、何がそれを無効にするのかを正確に知りたいと思います(特に、iostreamとは関係がなく、評価の順序やコンストラクターなどとの相互作用とは関係がないと思います)。それが問題ではない場合、それでは何ですか?

4

2 に答える 2

8

問題は、一時ストリーム オブジェクトに書き込んではいけないことです。これ:

std::ostream(coutbuf) << "blah";

の左側の引数operator<<()が右辺値であるため、期待どおりに機能しません。ただし、フリー関数としてオーバーロードされたすべての演算子は、左側の引数としてストリームへの非 const 参照を取ります。

std::ostream& operator<<(std::ostream&, ...);

右辺値は非 const 参照にバインドされないため、呼び出すことができません。

あなたの std lib 実装は<<forを無料の関数として実装しているため、 のメンバーであるconst char*いくつかにフォールバックする必要があると思われます。あなたの実装では、ポインターを として出力しているようです。<<std::ostreamvoid*

結論: 一時的なストリーム オブジェクトに書き込もうとしないでください。

于 2009-11-19T17:13:35.347 に答える
1

このような一時ストリーム オブジェクトは使用できません。一時変数に名前を付けます。

#include <iostream>

int main()
{
    std::streambuf *coutbuf = std::cout.rdbuf();
    std::ostream os(coutbuf);
    os << "test" << ": writing to cout using a separate ostream." << std::endl;
    return 0;
}
于 2009-11-19T17:15:42.940 に答える