Search code examples
c++booststdboost-log

Properly overload operator << in Boost.Log


In the Boost.Log documentation, it is said that

Note

The library uses basic_formatting_ostream stream type for record formatting, so when customizing attribute value formatting rules the operator<< must use basic_formatting_ostream instead of std::ostream.

However, throughout the documentation, all I see is overloading operator << on std::ostream rather than basic_formatting_ostream in the example code. For example, see the overload for the custom type severity_level here.

According to my tests, the overloads on std::ostream and basic_formatting_ostream both worked fine. So, I'm wondering what are the advantages of overloading on one instead of the other.


Solution

  • There is no problems in overloading just operator << (std::ostream&, ...), since formatting_ostream has

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

    where stream() returns std::ostream&. If you overload operator << with first arg formatting_ostream, than this can be used only with boost::log, if you overload for std::ostream&, then this can be used for boost::log and for another output.

    Quote from header file:

     * 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.