我目前正在写一个包装stringstream的类。我的总体目标是为我的字符串流提供线程安全<<(ostream)。我在弄清楚我要做什么的正确语法时遇到了麻烦。任何帮助将是最感激的!
下面您将找到我尝试过的内容。我知道这不是正确的语法,但这正是我要拍摄的。我当然不能重载<<操作符,并强迫用户使用AddValue,但这对于编写代码时快速简便地进行字符串操作不是理想的选择。
class WrappedStringStream
{
public :
WrappedStringStream() ;
template<typename T>
void AddValue( const T & value )
{
m_mutex.Lock() ;
//here I'd like to do something like m_stringstream << value, but of course since
//I'm overloading operator<< that won't work
m_mutex.Unlock() ;
}
friend std::ostream & operator<<( std::ostream & out, const WrappedStringStream & string )
{
string.AddValue( out ) ;
return out ;
}
protected :
std::stringstream m_stringstream ;
mutable Mutex m_mutex ;
}
如上所述,它无法编译,据我所知,因为我将WrappedStringStream传递为const参数并调用了非const的AddValue,导致了丢弃限定符错误。
答案 0 :(得分:-1)
这是解决方案
#include <iostream>
#include <sstream>
#include <mutex>
using namespace std;
class MutexWrapper
{
private:
mutex& m_mutex;
public:
MutexWrapper(mutex& mtx) : m_mutex(mtx) { mtx.lock () ; };
~MutexWrapper() { m_mutex.unlock () ; };
};
class WrappedStringStream
{
public :
WrappedStringStream() { };
template<typename T>
std::ostream & operator<<(const T& value)
{
MutexWrapper wrapper(m_mutex);
return m_stringstream << value;
}
void showStream()
{
cout << m_stringstream.str();
}
protected :
stringstream m_stringstream;
mutable mutex m_mutex ;
};
int main()
{
WrappedStringStream ws;
ws << "This is a string, " << 5 << 6.78;
ws.showStream();
return 0;
}
输出
This is a string, 56.78
=========编辑=========
最初我并不是很安静地了解提问者的最终目标,而只是专注于如何解决他的语法问题。在多线程环境中使用<<不是一个好主意。我们有一个Log类,在我们的日志类中,我们只有一个Log方法,该方法需要可变数量的参数。这样可以解决问题。
仍然有一种使用<<来锁定线程的解决方案,但真的很急,不建议这样做。缺点很明显-如果您忘记添加'LoggingStart'和'LoggingEnd',则可能会陷入僵局。
也要感谢@RemyLebeau,它应该返回* this而不是m_stringstream。
请参见下面的代码。
#include <iostream>
#include <sstream>
#include <mutex>
using namespace std;
class WrappedStringStream
{
public:
enum StreamSignals
{
LoggingStart,
LoggingEnd
};
WrappedStringStream() { };
std::ostream & operator<<(const StreamSignals& signal)
{
if (signal == LoggingStart)
m_mutex.lock();
else if (signal == LoggingEnd)
m_mutex.unlock();
return *this;
}
template<typename T>
std::ostream & operator<<(const T& value)
{
m_stringstream << value;
return *this;
}
void showStream()
{
cout << m_stringstream.str();
}
protected :
stringstream m_stringstream;
mutable mutex m_mutex ;
};
int main()
{
WrappedStringStream ws;
ws << WrappedStringStream::StreamSignals::LoggingStart;
ws << "This is a string, " << 5 << 6.78;
ws << WrappedStringStream::StreamSignals::LoggingEnd;
ws.showStream();
return 0;
}