我正在使用boost日志记录框架,该框架可能与该问题无关,但是我想使用LOG(sev)
形式的宏,其中sev
是日志级别之一,我可以标准化输出格式。
#define LOG_LOCATION \
boost::log::attribute_cast<boost::log::attributes::mutable_constant<int>>(boost::log::core::get()->get_global_attributes()["Line"]).set(__LINE__); \
boost::log::attribute_cast<boost::log::attributes::mutable_constant<std::string>>(boost::log::core::get()->get_global_attributes()["File"]).set(__FILE__); \
boost::log::attribute_cast<boost::log::attributes::mutable_constant<std::string>>(boost::log::core::get()->get_global_attributes()["Function"]).set(__func__);
#define LOG(sev) LOG_LOCATION BOOST_LOG_SEV(slg, sev)
extern boost::log::sources::severity_logger<boost::log::trivial::severity_level > slg;
在大多数情况下,当日志位于一行时,此代码段有效,但是,如果我使用if格式的话。
if(false) LOG(debug) << "Don't print this";
它总是打印消息。原因很明显,if适用于宏中的第一个语句,其余语句已执行,因此该语句将显示(没有行号)。
我不确定如何格式化此宏以使其正常工作。
答案 0 :(得分:1)
用逗号替换LOG_LOCATION
宏中三个函数调用末尾的分号。这样会将三个语句变成一个局部语句,在扩展宏结束后继续。
#define LOG_LOCATION \
boost::log::attribute_cast<boost::log::attributes::mutable_constant<int>>(boost::log::core::get()->get_global_attributes()["Line"]).set(__LINE__), \
boost::log::attribute_cast<boost::log::attributes::mutable_constant<std::string>>(boost::log::core::get()->get_global_attributes()["File"]).set(__FILE__), \
boost::log::attribute_cast<boost::log::attributes::mutable_constant<std::string>>(boost::log::core::get()->get_global_attributes()["Function"]).set(__func__),
如上所用,if
行将变为
if(false) a, b, c, BOOST_LOG_SEV(slg, sev) << "Don't print this";
(为简洁起见,用三个字母代替对set
的三个呼叫。)
如果BOOST_LOG_SEV
扩展为单个表达式,则可以使用。但是,BOOST_LOG_SEV
扩展为for
语句:
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()
因此有必要采用另一种方法。
您可以将“ LOG”定义为一个类(而不是宏),以将所有内容封装在这些宏中。
class LOG {
public:
LOG(int sev): sev(sev) { LOG_LOCATION; }
LOG &operator<<(const char *msg) {
BOOST_LOG_SEV(slg, sev) << msg;
return *this;
}
}
根据您的需求,可以添加operator<<
的其他重载来处理std::string
,int
,或者只是将其作为模板类。
在发送多个项目(LOG(debug) << "Number " << x << " found."
)时,这可能不如原始的高效,但可以作为单个语句使用。