boost.log和ostream怎么合作?

How to cooperate boost.log and ostream?

我正在使用 boost.log 作为我的日志组件。

真的很精彩!

但是boost.log在工作之前还有很多header要包括在内。 所以我封装了boost.log.

问题来了。 我们定义一个class.

class Point2D
{ 
public: 
    friend ostream& operator<<(ostream& strm, Point2D const& p);
private:
    double _x; double _y;
};
friend ostream& operator<<(ostream& strm, Point2D const& p){
    strm<<"("<<_x<<", "<<_y<<")";
    return strm;
}

在封装之前,下面的代码有效。

Point2D p;
BOOST_LOG_SEV(normal)<<p;

封装后,

// ------------ Log.h ----------
class Log 
{
public:
    static Log& instance();
    Log& operator<<(const char* str);
};
#define MY_LOG() Log::instance()

// ------------ Log.cpp ----------
BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(my_logger, src::logger_mt)
Log& Log::operator<<(const char* str){
    BOOST_LOG(my_logger)<<p;
}

// ------------ use.cpp -----------
Point2D p;
MY_LOG()<<p;  // !!! don't work, because "operator<<(std::ostream&, Point2D)" cannot be used directly by class Log.

谁能给我一个解决这个问题的提示?

Point2Doperator<< 重载在 std::ostream 或派生流 class 上运行,并且您的 Log class 不是流(即它不是从 std::ostream 派生的)。

你需要

  • 编写一个 operator<< 重载,将对 Log 的引用作为第一个参数,或者
  • 通过从 std::ostream 派生它并覆盖必要的虚拟成员函数来使 Log 成为一个流,或者
  • 修改 MY_LOG 使其 returns 引用 std::ostream 而不是 Log.

此外,无论您选择哪种方式,您都应该知道,按照现在的设计,您的 MY_LOGLog::operator<< 会在每个 生成一个日志记录=10=]调用,整个流式表达式没有一条记录。这可能不是您想要的,因此您需要设计 Log API 以提供显式成员来开始和结束日志记录,以便所有 operator<< 调用属于记录的操作在这两个调用之间完成。您可以在 Boost.Log.

中看到这是如何完成的