我有一个具有多个类的C ++项目。我想简化我的日志记录过程,以便可以创建一些自定义ostream对象log
,以便无论我想在何处打印日志消息,都可以编写log << my-message
。问题是我的每个类都有一个名称(存储为字符串),并且我希望ostream对象在日志消息之前给该类的名称加上前缀。因此输出如下所示:
name-of-class: my-message
如何在C ++中做到这一点?
我尝试创建一个具有名称变量的Logger类,然后在我的每个类中实例化该类的对象,然后将该类的名称设置为Logger对象的名称。但是这种方法无法扩展,因为一旦我连接了多个日志消息,每次都会打印该名称。
我还尝试使用可变参数的模板/函数,但是后来我无法传递诸如std::hex
,std::endl
等的参数。
答案 0 :(得分:1)
如果您可以直接在流缓冲区上工作,则无需重新定义大量提取器/插入器即可获得所需的功能。这基本上可以归结为使用标志来确定是否应打印初始日志消息名称。一旦写入,该标志就会变为false。
应该使用logger()
访问记录器,以便可以重置变量。
struct : std::streambuf {
std::ostream* os = &std::cout;
std::string msg;
bool insert;
void str(std::string const& s) { msg = s; }
int_type overflow(int_type c) override {
if (insert) {
(*os) << msg;
insert = false;
}
return os->rdbuf()->sputc(c);
}
int sync() override { return os->rdbuf()->pubsync(); }
} logbuf;
std::ostream& logger(std::string const& msg = "Message from me: ") {
logbuf.insert = true;
logbuf.str(msg);
static std::ostream os(&logbuf);
return os;
}
int main() {
logger() << "1"
<< " + "
<< "1 = " << 2 << '\n';
logger() << 3 << " - " << 3 << " = " << 0 << '\n';
}
输出:
我的来信:1 +1 = 2
来自我的消息:3-3 = 0