在过去的三个小时里,我对以下编译错误感到非常困惑。谁能告诉我这里发生了什么?
我试图将log :: formatter(标记如下)定义为自己的变量,因此可以在几个地方重复使用它。但是,尝试重新使用它时出现编译错误。
但是,如果我完全摆脱该变量,而是复制并粘贴代码,它就会编译。有没有搞错?有什么办法可以做我想要的吗?
boost::shared_ptr<log::core> logger = log::core::get();
logger->set_logging_enabled( enabled );
logger->set_filter(trivial::severity >= level);
logger->add_global_attribute(
"TimeStamp", attr::local_clock());
logger->add_global_attribute(
"ProcessID", attr::current_process_id());
logger->add_global_attribute(
"ThreadID", attr::current_thread_id());
// want this to be it's own variable
log::formatter fmt = expr::stream
<< "[" << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%d.%m.%Y %H:%M:%S.%f") << "] "
<< "[" << expr::attr< attr::current_process_id::value_type >("ProcessID") << "] "
<< "[" << expr::attr< attr::current_thread_id::value_type >("ThreadID") << "] "
<< "[" << expr::attr< std::string >("Channel") << "] "
<< "[" << expr::attr< severity_level >("Severity") << "]: "
<< expr::smessage
;
// so it can be reused here, but this is a compiler error
log::add_console_log(
std::clog, keywords::format=fmt);
// and here, too. But this is also a compiler error
log::add_file_log(
"test.log", keywords::format=fmt);
编译错误(使用clang ++)是:
In file included from ../src/util/logging/Logging.cpp:34:
In file included from /opt/boost-1.54.0/include/boost/log/utility/setup/console.hpp:22:
/opt/boost-1.54.0/include/boost/log/detail/sink_init_helpers.hpp:107:21: error: no matching function for call to 'acquire_formatter'
s.set_formatter(aux::acquire_formatter(args[keywords::format]));
^~~~~~~~~~~~~~~~~~~~~~
/opt/boost-1.54.0/include/boost/log/utility/setup/console.hpp:76:5: note: in instantiation of function template specialization 'boost::log::v2_mt_posix::aux::setup_format
boost::log::v2_mt_posix::sinks::synchronous_sink<boost::log::v2_mt_posix::sinks::basic_text_ostream_backend<char> >, boost::parameter::aux::tagged_argument<boost::log::v2
posix::keywords::tag::format, boost::log::v2_mt_posix::basic_formatter<char> > >' requested here
aux::setup_formatter(*pSink, args,
^
/opt/boost-1.54.0/include/boost/log/utility/setup/console.hpp:136:12: note: in instantiation of function template specialization 'boost::log::v2_mt_posix::aux::add_consol
g<char, boost::parameter::aux::tagged_argument<boost::log::v2_mt_posix::keywords::tag::format, boost::log::v2_mt_posix::basic_formatter<char> > >' requested here
return aux::add_console_log(strm, arg1);
^
../src/util/logging/Logging.cpp:121:2: note: in instantiation of function template specialization 'boost::log::v2_mt_posix::add_console_log<char, boost::parameter::aux::t
d_argument<boost::log::v2_mt_posix::keywords::tag::format, boost::log::v2_mt_posix::basic_formatter<char> > >' requested here
log::add_console_log(
^
/opt/boost-1.54.0/include/boost/log/detail/sink_init_helpers.hpp:80:33: note: candidate template ignored: failed template argument deduction
inline basic_formatter< CharT > acquire_formatter(const CharT* formatter)
^
/opt/boost-1.54.0/include/boost/log/detail/sink_init_helpers.hpp:85:33: note: candidate template ignored: failed template argument deduction
inline basic_formatter< CharT > acquire_formatter(std::basic_string< CharT, TraitsT, AllocatorT > const& formatter)
^
/opt/boost-1.54.0/include/boost/log/detail/sink_init_helpers.hpp:91:5: note: candidate template ignored: disabled by 'enable_if' [with FormatterT = boost::log::v2_mt_posi
asic_formatter<char>]
phoenix::is_actor< FormatterT >,
^
但是,如果我将其更改为此,则会编译:
boost::shared_ptr<log::core> logger = log::core::get();
logger->set_logging_enabled( enabled );
logger->set_filter(trivial::severity >= level);
logger->add_global_attribute(
"TimeStamp", attr::local_clock());
logger->add_global_attribute(
"ProcessID", attr::current_process_id());
logger->add_global_attribute(
"ThreadID", attr::current_thread_id());
// copy and paste the expression
log::add_console_log(
std::clog,
keywords::format =
(
expr::stream
<< "[" << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%d.%m.%Y %H:%M:%S.%f") << "] "
<< "[" << expr::attr< attr::current_process_id::value_type >("ProcessID") << "] "
<< "[" << expr::attr< attr::current_thread_id::value_type >("ThreadID") << "] "
<< "[" << expr::attr< std::string >("Channel") << "] "
<< "[" << expr::attr< severity_level >("Severity") << "]: "
<< expr::smessage
)
);
// copy and paste the expression again
log::add_file_log(
"test.log",
keywords::format =
(
expr::stream
<< "[" << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%d.%m.%Y %H:%M:%S.%f") << "] "
<< "[" << expr::attr< attr::current_process_id::value_type >("ProcessID") << "] "
<< "[" << expr::attr< attr::current_thread_id::value_type >("ThreadID") << "] "
<< "[" << expr::attr< std::string >("Channel") << "] "
<< "[" << expr::attr< severity_level >("Severity") << "]: "
<< expr::smessage
)
);
答案 0 :(得分:5)
log :: formatter类型是实际(非常复杂)表达式类型的包装器。由于某种原因,它不能与add_file / console_log一起使用。
如果您使用的是C ++ 11,则auto关键字将避免使用包装类:
auto fmt = expr::stream
<< ...
如果没有C ++ 11,模板函数参数将起作用:
template <class F>
void add_logs(const F & fmt)
{
log::add_console_log(std::clog, keywords::format = fmt);
log::add_file_log("test.log", keywords::format = fmt);
}
add_logs(expr::stream
<< ...
);