假设我们有几个级别的日志记录:跟踪、调试、信息、错误。我想知道是否有一种方法可以编写以下代码:
enum log_level = {trace, debug, info, error};
log_level global_log_level = info;
void log(log_level level, string& message){
if (level >= global_log_level){
std::cout << message << std::endl;
}
}
string create_message(){
...
}
log_level level = debug;
log (level, create_message());如果级别比global_severity_level小,则不调用global_severity_level。事实上,create_message可能很长,不管它创建什么字符串。如果有大量的“调试”日志,在非调试模式下运行时,这些日志可能会成为大量的开销。
我知道,如果函数"log“是宏,只有在严重性>minimal_severity时才调用create_message(),那么就可以这样做;但是没有宏就没有其他方法可以做到这一点吗?
编辑
在上面,我没有指定create_message,因为它可以是任何东西,特别是:
log(level, "Created object " + my_object.getName());在这种情况下,是否有一种方式来编写日志,这样就不会以相对透明的方式创建完整的字符串,以便程序员调用日志?
非常感谢
发布于 2013-02-02 19:31:55
类似于@sftrabbit,但正如@ipc所建议的那样。
使用模板来避免std::function,编译器可能能够将其内联,因此它最终可能会更快。
template< typename F >
void log(log_level level, F message_creator){
if (level >= global_log_level){
std::cout << message_creator() << std::endl;
}
}发布于 2013-02-02 18:50:44
有几种选择。一个有趣的方法是将create_message作为一个std::function<std::string()>传递并从log内部调用它。
void log(log_level level, std::function<std::string()> message_creator){
if (level >= global_log_level){
std::cout << message_creator() << std::endl;
}
}然后你会这样称呼它:
log(level, create_message);如果将任意表达式包装在lambda中,则可以将它们作为参数处理:
log(level, [&](){ return "Created object " + my_object.getName(); });如果您真的不想对参数进行评估(正如您在注释中所描述的那样),那么您需要检查调用之外的级别:
if (level >= global_log_level) {
log(level, create_message());
}发布于 2013-02-02 18:58:09
@sftrabbit答案优先。但是,如果您不想更改log(),就可以调用它:
log (level, (level >= global_log_level)? create_message() : "");https://stackoverflow.com/questions/14665184
复制相似问题