【问题标题】:Properly overload operator << in Boost.Log在 Boost.Log 中正确重载运算符 <<
【发布时间】:2015-10-02 08:02:53
【问题描述】:

Boost.Log documentation,据说

注意

库使用basic_formatting_ostream流类型进行记录格式化,所以在自定义属性值格式化时 规则 operator&lt;&lt; 必须使用 basic_formatting_ostream 而不是 std::ostream.

但是,在整个文档中,我看到的只是在示例代码中重载 operator &lt;&lt; 上的 std::ostream 而不是 basic_formatting_ostream。例如,查看自定义类型 severity_level here 的重载。

根据我的测试,std::ostreambasic_formatting_ostream 的重载都运行良好。所以,我想知道重载一个而不是另一个有什么好处。

【问题讨论】:

  • 使用std::ostream 的优势应该非常明显:您也可以将它用于“正常”输出。 :)

标签: c++ boost c++-standard-library boost-log


【解决方案1】:

重载operator &lt;&lt; (std::ostream&amp;, ...)没有问题,因为formatting_ostream

template< typename CharT, typename TraitsT, typename AllocatorT, typename T >
inline basic_formatting_ostream< CharT, TraitsT, AllocatorT >&
operator<< (basic_formatting_ostream< CharT, TraitsT, AllocatorT >& strm, T const& value)
{
    strm.stream() << value;
    return strm;
}

其中stream() 返回std::ostream&amp;。如果你用第一个参数formatting_ostream 重载operator &lt;&lt;,那么这只能用于boost::log,如果你为std::ostream&amp; 重载,那么它可以用于boost::log 和另一个输出。

引用头文件:

 * This stream wrapper is used by the library for log record formatting. It implements the standard string stream interface
 * with a few differences:
 *
 * \li It does not derive from standard types <tt>std::basic_ostream</tt>, <tt>std::basic_ios</tt> and <tt>std::ios_base</tt>,
 *     although it tries to implement their interfaces closely. There are a few small differences, mostly regarding <tt>rdbuf</tt>
 *     and <tt>str</tt> signatures, as well as the supported insertion operator overloads. The actual wrapped stream can be accessed
 *     through the <tt>stream</tt> methods.
 * \li By default, \c bool values are formatted using alphabetical representation rather than numeric.
 * \li The stream supports writing strings of character types different from the stream character type. The stream will perform
 *     character code conversion as needed using the imbued locale.
 * \li The stream operates on an external string object rather than on the embedded one. The string can be attached or detached
 *     from the stream dynamically.
 *
 * Although <tt>basic_formatting_ostream</tt> does not derive from <tt>std::basic_ostream</tt>, users are not required to add
 * special overloads of \c operator<< for it since the stream will by default reuse the operators for <tt>std::basic_ostream</tt>.
 * However, one can define special overloads of \c operator<< for <tt>basic_formatting_ostream</tt> if a certain type needs
 * special formatting when output to log.

【讨论】:

  • 但是插入basic_formatting_ostream 似乎比插入std::ostream 做更多的工作。例如,查看basic_formatting_ostreamconst char* 提供的重载operator &lt;&lt;
  • @Lingxi nope,basic_formatting_ostream 只是尽可能接近地实现basic_ostream 的接口。
  • 那么,Boost.Log 文档只是过时了还是什么?
  • @Lingxi no... 可能他们的意思是,如果日志格式应该与“正常”输出不同,那么您应该只为 record_formatting 编写formatting_ostream。
  • basic_formatting_ostream 不会为 std::ostream 已经支持的输出做更多的工作。包装器要么将运算符转发到std::ostream 特定的运算符,要么采用捷径,知道输出无论如何都会以字符串结尾,因此,如果有的话,它应该在这些情况下执行得更快。文档是正确的。
【解决方案2】:

如果你只重载operator&lt;&lt;(std::ostream),它将适用于每个流输出,包括basic_formatting_ostream。如果您只重载operator&lt;&lt;(basic_formatting_ostream),它将仅适用于输出到该类型的流。

但是,您可能希望重载两者,例如,如果您想向日志提供不同或更多信息(例如对象的地址)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    相关资源
    最近更新 更多