我正在尝试编写一个日志类,您可以在其中执行类似的操作
//Create an instance of a class
Log log;
log.debug() << "a string " << 42 << endl;
log.info() << "another string " << 41 << endl;
这将产生以下输出到标准输出
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() << “stuff”?这是一个非常简单的示例,在以后的版本中,将不再是字符串,而是时间戳、日期戳、用户名等。这就是为什么我试图让每个日志级别由不同的函数处理。
我猜我需要另一个运算符重载语句,但我只是想不出它需要什么。此外,当前的 << 模板运算符不喜欢 std::endl(如果我使用它就不会编译)所以我只是在顶部设置 endl = '\n'。
在此先感谢,期待尽可能多地学习。
最佳答案
听起来你想要的是你的 debug
和 info
函数返回类似 std::stringstream
的内容这将支持 operator<<
,但不知何故之后也会刷新输出。如果是这样,你最好使用类似 variadic template 的东西功能。
关于您的其他问题,std::endl
实际上是一个模板,所以它的类型不能用作T
对于 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> &))
. std::endl
是一个函数模板,它接受一个 ostream,附加一个换行符,然后刷新流。
我还应该注意到您的 debug
和 info
函数不返回值。如果您使用的是 GCC,默认情况下禁用此警告,但它可能是未定义行为的一个非常棘手的来源。使用 -Wreturn-type
在构建重要内容时启用它。
关于C++ 将流传递给类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23416307/