我正在尝试实现我自己的QDebug()样式调试输出流,这基本上是我到目前为止:
struct debug
{
#if defined(DEBUG)
template<typename T>
std::ostream& operator<<(T const& a) const
{
std::cout << a;
return std::cout;
}
#else
template<typename T>
debug const& operator<<(T const&) const
{
return *this;
}
/* must handle manipulators (endl) separately:
* manipulators are functions that take a stream& as argument and return a
* stream&
*/
debug const& operator<<(std::ostream& (*manip)(std::ostream&)) const
{
// do nothing with the manipulator
return *this;
}
#endif
};
Run Code Online (Sandbox Code Playgroud)
典型用法:
debug() << "stuff" << "more stuff" << std::endl;
Run Code Online (Sandbox Code Playgroud)
但我不想添加std :: endl;
我的问题基本上是,如何判断运算符<<的返回类型何时不被另一个运算符<<(以及附加endl)使用?
我可以想到实现这样的任何事情的唯一方法是创建一个打印的事物列表,与debug()创建的每个临时对象相关联,然后打印所有内容,以及尾随换行符(我可以做聪明的事情)就像在~debug()中插入空格一样,但显然这并不理想,因为我没有保证临时对象将被销毁,直到范围结束(或者我?).
Eva*_*ran 17
这样的事情会做:
struct debug {
debug() {
}
~debug() {
std::cerr << m_SS.str() << std::endl;
}
public:
// accepts just about anything
template<class T>
debug &operator<<(const T &x) {
m_SS << x;
return *this;
}
private:
std::ostringstream m_SS;
};
Run Code Online (Sandbox Code Playgroud)
哪个应该让你做这样的事情:
debug() << "hello world";
Run Code Online (Sandbox Code Playgroud)
我已经使用了像这样的模式结合锁来提供像日志系统一样的流,它可以保证日志条目是以原子方式编写的.
注意:未经测试的代码,但应该工作:-)
Bil*_*ill 10
Qt使用类似于@Evan的方法.有关实现的详细信息,请参阅qdebug.h的一个版本,但它们将所有内容流式传输到基础文本流,然后在销毁qDebug()返回的临时QDebug对象时刷新流和终止行.
当你写这是典型的用法:
debug() << "stuff" << "more stuff" << std::endl;
Run Code Online (Sandbox Code Playgroud)
你肯定打算每次使用它时构建一个调试对象吗?如果是这样,您应该能够通过调试析构函数添加换行符来获得所需的行为:
~debug()
{
*this << std::endl;
... the rest of your destructor ...
}
Run Code Online (Sandbox Code Playgroud)
这意味着你不能做这样的事情:
// this won't output "line1" and "line2" on separate lines
debug d;
d << "line1";
d << "line2";
Run Code Online (Sandbox Code Playgroud)