【问题标题】:Short circuit `operator<<` output in C++C ++中的短路`运算符<<`输出
【发布时间】:2012-08-03 16:48:24
【问题描述】:

我有一些代码中散布着这样的结构

if(debug) {
    Output << "f1: " << f1() << "\n";
}

现在我想做的是写一个流类Debug 我可以这样写

Debug << "f1: " << f1() << "\n";

如果设置了一些全局标志,那么这将生成输出,否则不会。

现在:这可以通过让Debug 返回一个流向/dev/null 的流来完成,这将吞噬输出。问题是f1() 仍然会被评估(并“渲染”成可能更昂贵的文本表示),这可能对性能非常不利。

现在我的问题是:是否有任何技巧可以跳过

的“评估”
"f1: " << f1() << "\n"

如果Debug 决定不进行任何输出?类似于 C++ 为 f() &amp;&amp; g() 所做的短路,如果 f()false 则不评估 g() (我认真考虑编写一个使用 &amp;&amp; 作为输出运算符的流类,但从我读到的简短- 重载时不进行电路operator&amp;&amp;)

【问题讨论】:

  • This related question 今天早些时候可能有解决方案。
  • @juanchopanza:这些问题仍然(可能)评估论点。我认为这不能按要求完成,除非您将格式切换为 DEBUGOUT("f1: " &lt;&lt; f1() &lt;&lt; "\n");
  • @MooingDuck 是的。他们只避免流式传输。
  • 这个 SO 看起来很相似:stackoverflow.com/questions/5035840/…
  • @MooingDuck: 除了使用evil macro的那个。

标签: c++


【解决方案1】:

你可以做的是定义这个宏:

#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";

【讨论】:

  • 这将容易受到悬空 else 不匹配的影响。
  • @MarkB: 可以通过定义if(!debug);else Output来修复。
  • 不错的标记。并感谢@ybungalobill 的建议。我已将答案更改为修复。
【解决方案2】:

如果您不反对宏,并且愿意接受该语法:

Debug( "f1: " << f() << '\n' );

这很简单:只需定义如下内容:

#define Debug( x ) debug != NULL && *debug << x;

不过,这有点危险,因为你不能像往常一样 将论点放在括号中的预防措施。 (另一方面, 我已经看到它在许多应用程序中使用过,没有问题。) 宏方法的另一个优点是允许您插入 __FILE____LINE__ 自动,如果你想的话。或者 通过定义 宏什么都不是。

【讨论】:

    【解决方案3】:

    我认为您可以通过创建一个包装昂贵函数调用的延迟评估器来做到这一点。您的流将知道它需要调用引用函数的延迟评估器类型,否则它不会对其进行操作,从而防止昂贵的调用。无调试流知道,您的代理评估器对象完全跳过评估。

    例如,调用可能如下所示:

    Debug << "123" << delay(f()) << "456" << std::endl;
    

    这确实涉及记住在调试行中调用延迟。它确实避免了对宏的需要,这在您的情况下可能是也可能不是关键问题。

    【讨论】:

      猜你喜欢
      • 2019-02-04
      • 1970-01-01
      • 1970-01-01
      • 2018-06-14
      • 2015-09-26
      • 1970-01-01
      • 2014-12-01
      • 2023-03-07
      • 2012-02-04
      相关资源
      最近更新 更多