【发布时间】:2016-09-17 11:21:46
【问题描述】:
应用程序有一个日志系统,允许在运行时启用或禁用其模块的日志功能。日志命令接受输入流(作为“sprintf”的安全替代方案;几乎没有比您的调试系统导致崩溃更烦人的情况了。
问题是,如果我执行以下操作:
logger.Trace << "Requests pending:" << buffer.findRequests();
并且findRequests() 具有很高的计算复杂度,即使禁用模块的 Trace 日志级别,也会在 Trace operator<< 方法内被拒绝之前执行搜索(在组装流时)。
显而易见的替代方法是在代码中乱扔:
if(logger.Trace.Enabled()) logger.Trace << ...
它不漂亮,也不舒服。我可以用使用if 的宏替换它,或者使用&& 短路的宏,更好一些(可以用作RValue,遵循Stream 哲学在禁用流上返回bool false):
#define TRACE if(logger.Trace.Enabled()) logger.Trace
#define TRACE dummyLogVar = logger.Trace.Enabled() && logger.Trace
两者都不是特别漂亮或安全。一位同事建议关闭:
logger.Trace([&](f){f << "Requests pending:" << buffer.findRequests();});
.Trace 仅在启用该级别时才会评估闭包。从逻辑上讲,这很好,但在语法上绝对可怕。打字乱七八糟:logger.Trace([&](f){f << ... ;}); 数百次?
有没有更简洁、安全和舒适的方法来防止对流进行评估?
【问题讨论】:
-
我认为闭包是唯一的方法。在引入闭包之前,我必须解决同样的问题,最后我不得不依赖宏和 C 风格的函数调用。
-
“从逻辑上讲,这很好,但在语法上绝对可怕。” 呵呵,欢迎使用 C++
-
@LightnessRacesinOrbit:很高兴我没有使用
<:&:>进行关闭。昨天偶然发现了那个,让我困惑了好一阵子。实际上<:是[的有向图。在这个时代,谁还在使用二合字母,为什么?以及为什么 C++11 扩展了二合字母和三合字母的集合?!是不是有人误会embedded programming,用带触屏键盘的安卓手机写PC端的应用? -
@SF.:“为什么 C++11 扩展了二合字母和三合字母的集合”它没有
-
@LightnessRacesinOrbit:哦,等等,它没有添加任何新的。它只是修改了对一个的解释。 当解析器遇到字符序列<::>时,。跨度>
标签: c++ c++11 conditional iostream