您的解决方案有几个问题。首先是你 按值通过stringstream
,它不支持复制。您需要 作为参考。第二个是在调用点的 的operator<<
重载返回值ostream&
,不stringstream
,由于 stringstream
不是一个基类的ostream&
(这是其他方式 轮),你不能初始化stringstream
(或stringstream&
) 与它。最后,没有operator<<
需要 stringstream
作为右手参数,因此 LogStream
函数中的语句无法工作。最后,无论如何,这对用户来说会有些尴尬。 operator<<
的日志是非成员, 与ostream&
非const引用作为第一个参数,所以您不能用 作为临时参数调用它们作为左参数。 (在你的榜样通话,当然 ,你忘了反正创建std::ostringstream
;它 不会编译,因为不存在<<
超载,这需要char const[]
或char const*
作为其左操作数。)
有几乎是解决所有这些问题的解决方法。东西 喜欢:
void LogStream(std::ostream& text)
{
std::ostringstream& s = dynamic_cast<std::ostringstream&>(text);
m_FileHandle << s.str() << std::endl;
}
处理所有的除了最后的问题;最后必须由客户端来处理 ,是这样的:
m_LogObject->LogStream(std::ostringstream().flush() << "..." << x);
(以std::ostream::flush()
调用返回非const引用 流,可用于初始化进一步std::ostream&
而当你。不能初始化一个临时的非const引用, 你可以调用它的非const成员函数)。
的这个客户端代码中的尴尬让我一般喜欢 更复杂的解决方案。我定义了一个特殊的LogStreamer
类, 是这样的:
class LogStreamer
{
boost::shared_ptr<std::ostream> m_collector;
std::ostream* m_dest;
public:
LogStreamer(std::ostream& dest)
, m_collector(new std::ostringstream)
, m_dest(&dest)
{
}
~LogStreamer()
{
if (m_collector.unique()) {
*m_dest << m_collector->str() << std::endl;
}
}
template <typename T>
LogStreamer& operator<<(T const& value)
{
*m_collector << value;
return *this;
}
};
和
LogStreamer LogStream() { return LogStreamer(m_FileHandle); }
,客户端代码可以写:
m_LogObject->LogStream() << "..." << x;
在我自己的代码:日志对象始终是一个单身人士,电话是 通过一个宏,它通过__FILE__
和__LINE__
到LogStream()
函数,并且最终目标ostream是一个特殊的streambuf,具有 特殊功能,由LogStream()
调用,它接受一个文件名和一个 行号,将它们连同时间戳一起输出到 的下一行输出,并缩进所有其他行。一种过滤 流缓冲的东西,如:
class LogFilter : public std::streambuf
{
std::streambuf* m_finalDest;
std::string m_currentHeader;
bool m_isAtStartOfLine;
protected:
virtual int overflow(int ch)
{
if (m_isAtStartOfLine) {
m_finalDest->sputn(m_currentHeader.data(), m_currentHeader.size());
m_currentHeader = " ";
}
m_isAtStartOfLine = (ch == '\n');
return m_finalDest->sputc(ch);
}
virtual int sync()
{
return m_finalDest->sync();
}
public:
LogFilter(std::streambuf* dest)
: m_finalDest(dest)
, m_currentHeader("")
, m_isAtStartOfLine(true)
{
}
void startEntry(char const* filename, int lineNumber)
{
std::ostringstream header;
header << now() << ": " << filename << " (" << lineNumber << "): ";
m_currentHeader = header.str();
}
};
(功能now()
,当然,返回std::string
与 时间戳或一个struct tm
,你已经写了一个<<
为tm
。)
什么不起作用?错误,错误的行为? – 2011-06-08 14:21:35