Небольшая альтернатива ответу Нима:
Создать
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
добавляет еще одну накладную.