6
inline std::ostream& operator<<(std::ostream& p, const std::vector<unsigned int>& vector){
  p << "[ ";
  for(auto i:vector){
    p << " "<< i << " ,";
  }
  p<< "]";
  return p;
}

#define LOG_DEBUG_MESSAGE BOOST_LOG_SEV(my_logger::get(), debug)


std::vector<unsigned int> test {1, 2, 3};
LOG_DEBUG_MESSAGE << "test "<< test;
std::cout << test  << std::endl;

Hello,

I overloaded my operator<< for a std::vector. When i use std::cout it works well, but with boost log i get following error:

boost/log/utility/formatting_ostream.hpp:710:19: error: cannot bind 'boost::log::v2_mt_posix::basic_formatting_ostream::ostream_type {aka std::basic_ostream}' lvalue to 'std::basic_ostream&&' strm.stream() << value;

/opt/gcc.4.9.1/include/c++/4.9.1/ostream:602:5: note: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits; _Tp = std::vector]' operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)

I have no idea why boost log is not working. It uses the same << operator or? On other examples with own classes it works well with overloading. I have no idea what I miss. Anyone has an idea how i can solve this error?

Hunk
  • 479
  • 11
  • 33
  • 1
    Boost log uses the overloaded output operator, but it probably does the overload on another class type and not `std::ostream`, which is why your code doesn't work. – Some programmer dude Oct 02 '14 at 07:18
  • 2
    As an experiment, can you try defining this `<<` operator in the std namespace and confirm if it compiles? – bobah Oct 02 '14 at 07:31
  • Maybe your traits types don't match? Try defining `operator<<` as a template `template inline std::basic_ostream& operator<<(std::basic_ostream& p, //etc`. – user657267 Oct 02 '14 at 07:40
  • 2
    bobah is correct, if you define the function in the namespace then it all works correctly. `namespace std { signature here; }` `std::ostream& std::operator<<() {}` – Kurt Feb 24 '15 at 16:55

1 Answers1

6

'boost::log::basic_formatting_ostream is not derived from std::ostream.

You should overload operator << for std::vector and the overloaded operator should take boost::log::formatting_ostream& as its first parameter.

Check the modified code example below:

inline boost::log::formatting_ostream& operator<<(boost::log::formatting_ostream& p,  std::vector<int>& vector)
{
        p << "[ ";
        for(auto i:vector){
            p << " "<< i << " ,";
        }
        p<< "]";
        return p;
}
Nipun Talukdar
  • 4,975
  • 6
  • 30
  • 42
  • 1
    Actually you can just overload std::ostream as mentioned in other posts, for instance in http://stackoverflow.com/questions/32902904/properly-overload-operator-in-boost-log – Lofty Lion Dec 19 '15 at 02:30
  • 2
    However you need to get it in the *same namespace* as the data type you are overloading for, for example in the case of _point_xy_ of boost geometry: `namespace boost { namespace geometry { namespace model { namespace d2 { template inline std::ostream & operator<< (std::ostream &os, point_xy const &pt) { os << "[point_xy: " << pt.x() << ", " << pt.y() << "]"; return os; } }}}} ` – Lofty Lion Dec 19 '15 at 02:37
  • if you use `auto` then use reference as well `for (auto &i : vector) {..}` to avoid copying when vector's type is changed – Maksym Ganenko Aug 12 '17 at 07:46