Nimの答えのわずかな代替:
作成
class LockedLog {
static MutEx mutex; // global mutex for logging
ScopedLock lock; // some scoped locker to hold the mutex
Logger &oLogger; // reference to the log writer itself
public:
LockedLog(Logger &oLogger) : oLogger(oLogger), lock(mutex) {}
template <typename T>
LockedLog &operator<<(const T &value) { oLogger << value; return *this; }
};
そして、次のいずれかを実行します。
LockedLog(oLogger) << "Log this" << " and this " << " and " << 10 << endl;
またはLogger::operator<<
、通常のメソッドに変更し、 でこのメソッドを呼び出しLockedLog::operator<<
、キャスト演算子を に追加しLogger
ます。
operator LockedLog() { return LockedLog(*this); }
これにより、現在のコードにロックが追加されます。
更新:これはすべての呼び出しをロックし、引数の評価をロックすることoperator<<
さえあります(コンパイラが最初に左または右の引数を評価し、選択するかどうかによって異なります)。それを減らすには、次のことができます。
class LockedLog {
static MutEx mutex; // global mutex for logging
std::stringstream buffer; // temporary formatting buffer;
Logger &oLogger; // reference to the log writer itself
public:
LockedLog(Logger &oLogger) : oLogger(oLogger), lock(mutex) {}
template <typename T>
LockedLog &operator<<(const T &value) { buffer << value; return *this; }
~LockedLog() { ScopedLock lock(mutex); oLogger << buffer.str() << std::flush; }
};
しかし、stringstream
別のオーバーヘッドが追加されます。