是否可以隐藏类似BOOST_LOG_TRIVIAL(lvl)的宏

时间:2019-04-03 07:40:58

标签: c++ boost

我在一个项目中使用boost.log已有一段时间了,这是一个非常不错的日志库。 但是要使用像BOOST_LOG_TRIVIAL(lvl)这样的基本日志,我需要包含boost/log/trivial.hpp,这将导致很多与Boost相关的事情都受到限制。

是否有任何方式(例如使用包装器或别名)来“隐藏” boost/log/trivial.hppBOOST_LOG_TRIVIAL(lvl),所以我可以确定任何其他开发人员只能调用BOOST_LOG_TRIVIAL(lvl)的包装版本?

一开始我以为BOOST_LOG_TRIVIAL(lvl)是一个简单的流对象,但是后来我发现它将被扩展为:

#define BOOST_LOG_STREAM_WITH_PARAMS_INTERNAL(logger, rec_var, params_seq)\
    for (::boost::log::record rec_var = (logger).open_record((BOOST_PP_SEQ_ENUM(params_seq))); !!rec_var;)\
        ::boost::log::aux::make_record_pump((logger), rec_var).stream()

这里有一个for循环,我不知道如何包装它。

1 个答案:

答案 0 :(得分:0)

这是复制宏正在执行的操作的重要任务。您也需要一个宏,但是如果您想将所有增强细节隐藏在实现单元中,则需要以某种方式复制方法调用。

首先,您需要在boost::log::record周围包装一个包装,然后在boost::log::record_pump<>周围包装一个包装,最后是制作包装实例的方法。最终结果应如下所示:

namespace foo {
  enum severity {
    debug, info, warn, error;
  }

  struct record {
    // use pimpl to hide
  };

  struct record_pump {
    // use pimpl to hide
  };

  // This will call the trivial logger to create a record and then
  // wrap with your record
  record make_record(severity lvl);

  // This method will call the boost `boost::log::make_record_pump` method
  // with the trivial logger and wrap the resulting `record_pump<T>` by your wrapper
  record_pump make_record_pump(record& rec);  
}

然后声明一个看起来像boost宏的宏-请记住,您需要在自己的枚举中公开级别

#define LOG(lvl) \
for (auto rec = foo::make_record(lvl); !!rec;) \
  foo::make_record_pump(rec).stream()

您需要实现recordrecord_pump接口的必要位。