我有一些代码像这样的构造
if(debug) {
Output << "f1: " << f1() << "\n";
}
现在我要做的是编写一个流类Debug
,我可以像这样编写它
Debug << "f1: " << f1() << "\n";
如果设置了某个全局标志,那么这将生成输出,否则不会。
现在:通过使Debug
返回流向/dev/null
的流来吞下输出,可以非常轻松地完成此操作。问题是f1()
仍然被评估(并'渲染'成文本表示,这可能会更昂贵),这可能对性能非常不利。
现在我的问题是:是否有任何技巧可以跳过
的'评估'"f1: " << f1() << "\n"
完全如果Debug
决定不应该输出?类似于C ++对f() && g()
所做的短路,g()
如果f()
为false
则不评估&&
(我认真考虑编写使用operator&&
的流类作为输出操作符,但是从我读到的短路操作中没有为重载{{1}})
答案 0 :(得分:5)
你可以做的是定义这个宏:
#define Debug_Stream \
if(!debug); else Output
这样就可以了:
Debug_Stream << "f1: " << f1() << "\n";
等同于:
if(debug) {
Output << "f1: " << f1() << "\n";
}
但字面上(加上空白以便于阅读)
if(!debug);
else
Output << "f1: " << f1() << "\n";
答案 1 :(得分:4)
如果您对宏不感兴趣,并愿意接受语法:
Debug( "f1: " << f() << '\n' );
非常简单:只需定义如下内容:
#define Debug( x ) debug != NULL && *debug << x;
然而,这有点危险,因为你不能照常采取
将论据放在括号中的预防措施。 (另一方面,
我已经看到它在许多应用程序中使用,没有问题。)
宏方法具有允许您插入的附加优势
如果您愿意,可以自动__FILE__
和__LINE__
。或者
通过定义,有条件地完全禁止所有代码
宏没什么。
答案 2 :(得分:2)
我认为你可以通过创建一个包含昂贵函数调用的延迟求值器来实现这一点。您的流将知道它需要调用引用函数的延迟求值器类型,否则它不会操作它,从而阻止昂贵的调用。无调试流知道您的代理评估程序对象只是完全跳过评估。
例如,呼叫可能如下所示:
Debug << "123" << delay(f()) << "456" << std::endl;
这确实涉及记住在调试行中调用延迟。它确实避免了对您的情况可能或可能不是关键问题的宏的需要。