元の質問
これを実行できるようにすることを目標とするロギング クラスを作成しています。
// thread one
Logger() << "Some string" << std::ios::hex << 45;
// thread two
Logger() << L"Some wide string" << std::endl;
現在、私の Logger ヘッダーは次のようになっています。
#pragma once;
#include <ostream>
class Logger
{
public:
Logger();
~Logger();
std::ostream* out_stream;
};
template <typename T>
Logger& operator<< (Logger& logger, T thing) {
*logger.out_stream << thing;
return logger;
}
このクラスに関する注意事項:
- クロス プラットフォームの互換性は問題ではありません。
- Logger.cpp の内部には、「実際の」ostream の作成を処理するシングルトン クラスがあります。
- Logger コンストラクターとデコンストラクターは、シングルトンの必要なロックを実行します。
3 つの問題があります。
- operator<< 関数をフレンドまたはメンバーにして、out_stream をプライベートとして設定するにはどうすればよいですか?
- operator<< 関数をマニピュレータで機能させるにはどうすればよいですか?
- T が WCHAR* または std::wstring の場合、out_stream に渡す前に char* または std::string に変換するように特殊化を追加するにはどうすればよいですか? (私は変換を行うことができます。私の場合、高いユニコード文字を失うことは問題ではありません。)
回答で学んだことの要約:
- 後ではなく、友人の前にテンプレートを置きます。
- std::ios::hex はマニピュレータではありません。std::hex はマニピュレータです。
最終結果
#pragma once
#include <ostream>
#include <string>
std::string ConvertWstringToString(std::wstring wstr);
class Logger
{
public:
Logger();
~Logger();
template <typename T>
Logger& operator<< (T data) {
*out << data;
return *this;
}
Logger& operator<< (std::wstring data) {
return *this << ConvertWstringToString(data);
}
Logger& operator<< (const wchar_t* data) {
std::wstring str(data);
return *this << str;
}
private:
std::ostream* out;
};