私は本当に単純なスレッドセーフなロガーを書こうとしています。理想的には、 のように機能するようにしたいと考えていましたstd::cout
。この場合、オペレーターをオーバーロードするだけ<<
で、魔法のようにすべてがログに表示されます。私はWindowsマシンを使用しているので、試したアプローチは次のとおりです。
// Threadsafe logger
class Logger
{
public:
Logger()
{
InitializeCriticalSection(&s);
}
~Logger()
{
DeleteCriticalSection(&s);
}
void Log(std::ostream const& os)
{
EnterCriticalSection(&s);
//std::cout << static_cast<std::stringstream const&>(os).str();
std::cout << os.rdbuf();
LeaveCriticalSection(&s);
}
private:
CRITICAL_SECTION s;
};
関数に対して 2 つのアプローチを試みたことに注意してくださいLog()
。私が an を受け入れる理由は、オペレーターが呼び出された後に a が生成するように見えるからostream
です。このコードを実行すると、関数の両方のバリアントが同じように失敗します。stringstream
<<
Log()
#include <iostream>
#include <sstream>
#include <Windows.h>
int main(int argc, char* argv[])
{
Logger logger;
//logger.Log(std::stringstream("Test"));
logger.Log(std::stringstream("Another ") << "test");
std::cin.get();
}
最初の行 ("Test") の出力は正しく機能し、Log 関数の両方のバリアントを使用して正しく表示されます。2 行目は、マングルされた出力を出力します。
testher
これは明らかにtest
上書きされていAnother
ます。これらのストリームの仕組みについて何が欠けていますか? flush
問題が解決することを期待して電話をかけてみましたが、何もしませんでした。
スレッドセーフロガーがストリームで正しく動作するようにするにはどうすればよいですか?