C++中懒惰登录
Lazy logging in C++
假设我们有几个级别的日志记录:跟踪、调试、信息、错误。我想知道是否有办法编写以下代码:
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,则无需调用create_message。事实上,create_message可以很长,不管它创建了一个字符串。如果有很多"调试"日志,则在非调试模式下运行时,这些日志可能会成为巨大的开销。
我知道如果函数"log"是一个宏,则有可能这样做,只有在严重性> minimal_severity时才调用create_message();但是没有宏没有另一种方法可以做到这一点吗?
编辑
在上面,我没有指定create_message,因为它可以是任何东西,特别是:
log(level, "Created object " + my_object.getName());
在这种情况下,有没有办法编写日志,以便不以相对透明的方式为程序员调用日志创建完整的字符串?
非常感谢
与@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;
}
}
有几种选择。一个有趣的方法是将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());
}
最好
@sftrabbit答案。但是如果你不想改变 log(),你可以调用它:
log (level, (level >= global_log_level)? create_message() : "");
您可以创建宏
#define log(level, message) {
if(level >= global_log_level) {
cout << message; }}
现在,如果您调用
log(debug, create_message());
create_message则只有在调试级别是所需的调试级别时才会被调用。相关文章:
- 密码登录程序将永远循环并显示不正确的结果
- 如何检查cURL是否成功登录?c ++
- 在 Tizen 中登录特定文件?
- 如何在 c++ 中将密码和用户名保存到 .txt 文件中.如果用户尝试登录,我仍然希望能够检索它们
- Win7 C++ - 从以用户身份登录的服务启动可执行文件的问题
- 在主窗口之前显示登录对话框并隐藏主窗口按钮
- 如何使用 libcurl 登录本网站?(C++)
- 如何使用 Apache C 模块登录到文件
- 用户注销/登录后,创建托盘图标时出现罕见错误
- 将正在运行的程序的用户名与登录到Windows的用户名进行比较
- 使用二进制文件的用户名和登录系统
- C++登录面板以查看 cout
- 从C++ Windows 服务中获取当前登录的用户名
- 是否有任何 C 函数或 API 来获取当前登录用户下运行的进程列表
- 不会在登录名中读取C++我的文件
- 尝试制作登录程序
- QT MySql 数据库检查登录名和密码以登录
- 与远程登录客户端协商回声
- 如何使用 cURL 防止在解析服务器中进行多次登录
- 如何从远程计算机中获取当前登录的用户名