【问题标题】:Lazy evaluation and/or flexible macro names惰性求值和/或灵活的宏名称
【发布时间】:2015-03-26 16:06:23
【问题描述】:

我有一个简单的单头日志库。我想将它“嵌入”到我编写的其他库中,以便用户可以有选择地为应用程序的不同部分打开日志记录。我不想添加任何依赖项,这就是单头性质如此吸引人的原因。为了使同一日志库的不同副本不会相互冲突,我可以将单独的副本粘贴到目标库的命名空间中,隔离所有需要隔离的内容。这部分很简单。

但是,有一个问题。日志库有一个宏,LOG_SEV(severity),它实际上用于将消息粘贴到特定的流中。宏的原因是我需要在前面加上某种 if (logging conditions hold) ... 以确保对消息进行惰性评估。

作为一个宏,它会污染全局命名空间,我至少会收到警告消息(可能还有冲突)。我想知道是否有办法解决这个问题。进行惰性求值的其他方式(在 C++03 中,而不是 C++11 中),或者使用目标库名称扩充宏名称的某种方式,将 LOG_SEV(severity) 转换为 LOG_SEV_mylib(severity)。或者这是没有希望的?

【问题讨论】:

  • 你能提供一个最小的代码示例吗?

标签: c++ logging macros lazy-evaluation c++03


【解决方案1】:

C++03(或更高版本)可以使用 boost::proto 生成尚未计算的表达式对象。

他们的"hello world" example(逐字,如下)接近你所描述的。

evaluate 函数中想象您的日志记录条件

#include <iostream>
#include <boost/proto/proto.hpp>
#include <boost/typeof/std/ostream.hpp>
using namespace boost;

proto::terminal< std::ostream & >::type cout_ = { std::cout };

template< typename Expr >
void evaluate( Expr const & expr )
{
    proto::default_context ctx;
    proto::eval(expr, ctx);
}

int main()
{
    evaluate( cout_ << "hello" << ',' << " world" );
    return 0;
}

【讨论】:

  • 非常有趣。我想这个想法的关键(如果我想避免将boost::proto 作为依赖项)是重载terminal 的运算符,构建一个表达式,并仅在条件成立时对其进行评估。我想我可以让它看起来比传递给evaluate() 更干净;像建立一个临时的和评估的破坏。非常感谢您;这是一个很好的解决方案。
  • 其实,等一下。这似乎有问题。如果表达式中有一个(昂贵的)函数调用,比如cout_ &lt;&lt; expensive(),无论如何它都会被评估。我想避免这种可能性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 2010-11-12
相关资源
最近更新 更多