6

The following code works as expected with boost 1.57:

#include <iostream>
#include <boost/log/trivial.hpp>

struct Foo
{
    int d=1;
};

std::ostream& operator<<(std::ostream& out, const Foo& foo)
{
    out << "Foo: " << foo.d;
    return out;
}

int main()
{
    BOOST_LOG_TRIVIAL(info) << Foo();
    return EXIT_SUCCESS;
}

with boost 1.59 the same code fails. The first gcc error message is:

error: no match for ‘operator<<’ (operand types are ‘boost::log::v2s_mt_posix::basic_record_ostream’ and ‘Foo’)

Neither the documentation nor the release notes document what needs to be changed.

Dimitris Dakopoulos
  • 683
  • 1
  • 6
  • 18
Marios V
  • 1,174
  • 9
  • 15
  • Live version: http://melpon.org/wandbox/permlink/Xn1hDoe7Zg7cynRX Looks like `enable_if_formatting_ostream` is broken. – ForEveR Aug 24 '15 at 16:38

1 Answers1

4

Live version Looks like problem is in enable_if_formatting_ostream struct. It was added in this commit. And looks like

template< typename StreamT, typename R >
struct enable_if_formatting_ostream {};
template< typename CharT, typename TraitsT, typename AllocatorT, typename R >
struct enable_if_formatting_ostream< basic_formatting_ostream< CharT, TraitsT, AllocatorT >, R > { typedef R type; };

And now operator << is

template< typename StreamT, typename T >
inline typename boost::log::aux::enable_if_formatting_ostream< StreamT, StreamT& >::type
operator<< (StreamT& strm, T const& value)

Before it was

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)

and since record_ostream is derived from formatting_ostream compiler can find overload, but now not, since SFINAE is used and struct will have type typedef only when formatting_ostream is used. And this can be workaround for this case.

ForEveR
  • 55,233
  • 2
  • 119
  • 133