我正在尝试编译:
#include <boost/log/trivial.hpp>
int main(int argc, char* argv[]) {
BOOST_LOG_TRIVIAL(info) << "test Boost.Log";
true ? 0 : BOOST_LOG_TRIVIAL(info) << "this fails";
}
编译命令:
clang++ main.cc -o main \
-lboost_log -lboost_log_setup -lboost_thread -lboost_system -pthread --static
上面抛出错误:
main2.cc:5:18: error: expected expression
true ? 0 : BOOST_LOG_TRIVIAL(info) << "this fails";
^
/usr/local/include/boost/log/trivial.hpp:113:5: note: expanded from macro 'BOOST_LOG_TRIVIAL'
BOOST_LOG_STREAM_WITH_PARAMS(::boost::log::trivial::logger::get(),\
^
/usr/local/include/boost/log/sources/record_ostream.hpp:317:5: note: expanded from macro 'BOOST_LOG_STREAM_WITH_PARAMS'
BOOST_LOG_STREAM_WITH_PARAMS_INTERNAL(logger, BOOST_LOG_UNIQUE_IDENTIFIER_NAME(_boost_log_record_), params_seq)
^
/usr/local/include/boost/log/sources/record_ostream.hpp:306:5: note: expanded from macro 'BOOST_LOG_STREAM_WITH_PARAMS_INTERNAL'
for (::boost::log::record rec_var = (logger).open_record((BOOST_PP_SEQ_ENUM(params_seq))); !!rec_var;)\
^
1 error generated.
以上是我在尝试创建宏时遇到的问题:
#define LOG_IF(lvl, condition) \
!(condition) ? 0 : BOOST_LOG_TRIVIAL(lvl)
运行g ++以扩展宏(g++ -E -C -P -o pre.cc main.cc
):
int main(int argc, char* argv[]) {
for (::boost::log::record _boost_log_record_4 = (::boost::log::trivial::logger::get()).open_record((::boost::log::keywords::severity = ::boost::log::trivial::info)); !!_boost_log_record_4;) ::boost::log::aux::make_record_pump((::boost::log::trivial::logger::get()), _boost_log_record_4).stream() << "test Boost.Log";
true ? 0 : for (::boost::log::record _boost_log_record_5 = (::boost::log::trivial::logger::get()).open_record((::boost::log::keywords::severity = ::boost::log::trivial::info)); !!_boost_log_record_5;) ::boost::log::aux::make_record_pump((::boost::log::trivial::logger::get()), _boost_log_record_5).stream() << "this fails";
}
它失败的原因很明显(表单编译错误)。但在这一点上,我不知道如何解决它。
答案 0 :(得分:0)
正如@KennyTM建议:
#define LOG_IF(lvl, condition) \
if (condition) BOOST_LOG_TRIVIAL(lvl)
效果很好(谢谢!)。
但是我仍然对条件表达式是否可以与Boost记录宏一起使用感兴趣。
答案 1 :(得分:0)
答案就在您粘贴的错误消息中。经过几个中间步骤后,BOOST_LOG_TRIVIAL
扩展为for
语句。三元运算符形成表达式,并且语句不能构成基本C系列语法中表达式的直接部分,因此失败。 for
对于语句的操作是不可或缺的(它提供了一种方法,可以在左侧的部分之后执行某些操作,或者通过在前面插入额外的语句或者通过创建一个范围块),所以只需重写宏不容易完成。
如果你想要一个快速而又狡猾的建议,你可以使用GCC语句表达式,或者可能使用lambdas(噪音很大但标准):
true ? ({0;}) : ({ BOOST_LOG_TRIVIAL(info) << "this fails"; });
如果你想要更多......某种东西......看起来与原版大致相似的解决方案,你可以尝试将它包装在一个包含的对象中:
#define LOG_TRIVIAL_EXPR(inf) TrivLogger([](std::string msg){ BOOST_LOG_TRIVIAL(inf) << msg; })
template<typename M>
class TrivLogger {
typedef std::function<void(std::string)> F;
F thunk;
TrivLogger(F th) : thunk(th) {}
TrivLogger<M> operator<<(std::string msg) {
thunk(msg); return this;
}
}
//...
true ? 0 : LOG_TRIVIAL_EXPR(info) << "this should work";
(说实话我不知道我是否做得对......)