我正在尝试编写一个日志类,您可以在其中执行此类操作
//Create an instance of a class
Log log;
log.debug() << "a string " << 42 << endl;
log.info() << "another string " << 41 << endl;
这将产生以下输出到stdout
Info: a string 42
Debug: another string 41
这是迄今为止我能够实现的目标
#include <iostream>
#include <string>
#include <sstream>
#define endl '\n'
using std::cout;
using std::string;
using std::stringstream;
class Log {
public:
Log () {}
~Log() {}
//Create buffer to store everything
stringstream buffer;
//Create templase class to overload <<
template <class T>
inline Log & operator << (T data) {
buffer << data;
return *this;
}
inline Log & debug() {
print("Debug: ");
}
inline Log & info() {
print("Info: ");
}
inline void print(string type) {
//Display the contents of the buffer to standard output
cout << type << buffer.str();
//Clear the buffer
buffer.str(string());
}
};
int main() {
Log log;
log << "Hello " << "World " << 5 << " " << 2.3 << endl;
log.debug();
log << "Hello Again " << 42 << endl;
log.info();
return 0;
}
这会产生正确的输出,但这样每行日志记录占用两行代码并且非常麻烦。我可以做任何事情我可以做log.debug()&lt;&lt; &#34;东西&#34 ;?这是一个非常简单的示例,在以后的版本中,而不仅仅是一个字符串,会有时间戳,日期戳,用户名等。这就是为什么我试图让每个日志级别由不同的函数处理。
我猜我还需要另一个运算符重载语句,但我无法弄清楚它需要什么。此外,当前&lt;&lt;模板运算符不像std :: endl(如果我使用它就不会编译)所以我只设置endl =&#39; \ n&#39;在顶部。
提前致谢,期待尽可能多地学习。
答案 0 :(得分:0)
听起来您想要的是debug
和info
函数返回类似std::stringstream
的内容,支持operator<<
,但不知何故也会在之后刷新输出。如果是这样,那么最好使用类似variadic template功能的东西。
至于您的其他问题,std::endl
实际上是一个模板,因此其类型不能用作T
的{{1}}。这是为什么不值得尝试重新实现流功能的一个例子。允许您编写Log::operator<< <T> (T)
的重载声明为<< std::endl
。 template <class _CharT, class _Traits> basic_ostream<_CharT, _Traits> & operator<<(basic_ostream<_CharT, _Traits>&, basic_ostream<_CharT, _Traits> &(basic_ostream<_CharT, _Traits> &))
是一个函数模板,它接受一个ostream,附加换行符并刷新流。
我还应注意,您的std::endl
和debug
函数未返回值。如果你正在使用GCC,默认情况下会禁用此警告,但它可能是一个非常棘手的未定义行为来源。在构建重要内容时使用info
启用它。