2013-07-20 52 views
4

在过去的三个小时里,我被以下编译错误彻底搞糊涂了。有人能告诉我这里发生了什么吗?Boost Log - 为什么不编译?

我试图将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); 

编译错误(用铛++)是:

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 
    ) 
); 

回答

5

日志::格式化器类型是包装实际(相当复杂)表达式类型。由于某些原因,它不能与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 
    << ... 
);