我想设计一个具有以下特点的日志功能:
- 基于 std::string 而不是 char*
- 支持可变数量的变量,例如 printf
- 接受作为第一个参数的严重性级别
- 避免严重级别低于日志级别时的格式化开销
- 像 printf 一样简单,或者几乎如此
我倾向于使用 boost::format 因为它的自动类型转换。但这里有一些我看到的问题:
它的语法有点尴尬:有点难看format("Mgr %s on pid %d is in state %s" % mgr % pid % s)
(变量的列表性质没有逗号就不那么明显了)。日志调用如下所示:
mylog(INFO, format("Mgr %s on pid %d is in state %s" % mgr % pid % s));
更糟糕的是,是否有可能实现 mylog() 来检查我们是否在构造格式对象 之前记录了 INFO 消息?
我想到的另一种看起来更接近 printf 的方法是
mylog(INFO, "Mgr %s on pid %d is in state %s", mgr, pid, s);
甚至
mylog_info("Mgr %s on pid %d is in state %s", mgr, pid, s);
实现将类似于:
mylog(int severity, string pattern, ...) {
if (severity >= LOGLEVEL) {
boost::format fmt(pattern);
for parm /* remaining parameters */ {
fmt % parm; // feed into format one at a time
}
}
}
这肯定会推迟格式对象的构建,直到需要它。但是据我所知,在遍历变量参数列表时,无法判断您何时到达终点!
有人可以建议一种语法上简单的技术来实现这一点吗?
注意:我有 g++ 4.4,它不支持所有的 c++11(虽然它支持可变参数模板)