1

Looking at this old post I too am trying to put together an ostream << operator() but keep running in to compile problems. I've tried the namespace suggestions, both std:: and log4cxx::helpers, but am getting nowhere.

I have a vector<uint8_t> that I would like to dump into LOG4CXX_DEBUG(), etc. I have this so far:

ostream& operator<<(ostream& os, const vector<uint8_t>& bs)
{
    ios_base::fmtflags oldFlags = os.flags();
    streamsize oldPrec = os.precision();
    char oldFill = os.fill();

    int s = bs.size();
    os << setfill('0') << uppercase << hex;
    for (int i = 0; i < s; ++i) {
        os << "0x" << setw(2) << (int)bs[i] << ' ';
    }

    os.flags(oldFlags);
    os.precision(oldPrec);
    os.fill(oldFill);

    return os;
}

The GNU g++ compiler spits back something like the following:

Compiling StationControllertest.cpp... In file included from /usr/include/log4cxx/logger.h:32:0,
                 from ./Configuration.h:15,
                 from StationController.h:4,
                 from StationControllertest.cpp:14:
/usr/include/log4cxx/helpers/messagebuffer.h: In function ‘std::basic_ostream<char>& log4cxx::helpers::operator<<(log4cxx::helpers::CharMessageBuffer&, const V&) [with V = std::vector<unsigned char>]’:
StationControllertest.cpp:474:5:   instantiated from here
/usr/include/log4cxx/helpers/messagebuffer.h:190:47: error: cannot bind ‘std::basic_ostream<char>’ lvalue to ‘std::basic_ostream<char>&&’
/usr/include/c++/4.6/ostream:581:5: error:   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<char>, _Tp = std::vector<unsigned char>]’
makefile:120: recipe for target 'StationControllertest.o' failed
make: *** [StationControllertest.o] Error 1

EDIT: Here is an example program

#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <vector>
#include <stdint.h>
#include <log4cxx/logger.h>
#include <log4cxx/propertyconfigurator.h>

using namespace std;
using namespace log4cxx;
using namespace log4cxx::helpers;

static LoggerPtr logger(Logger::getLogger("log4test"));


ostream& operator<<(ostream& os, const vector<uint8_t>& bs)
{
    ios_base::fmtflags oldFlags = os.flags();
    streamsize oldPrec = os.precision();
    char oldFill = os.fill();

    int s = bs.size();
    os << setfill('0') << uppercase << hex;
    for (int i = 0; i < s; ++i) {
        os << "0x" << setw(2) << (int)bs[i] << ' ';
    }

    os.flags(oldFlags);
    os.precision(oldPrec);
    os.fill(oldFill);

    return os;
}


int main(int argc, char* argv[])
{
    PropertyConfigurator::configure("Log4cxxConfig.cfg");

    vector<uint8_t> v = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a };

    cout << v << endl;
    LOG4CXX_INFO(logger, v);
}

The cout statement compiles and works but not the LOG4CXX_INFO macro. Thanks!

Community
  • 1
  • 1
Kelly Beard
  • 684
  • 1
  • 8
  • 20
  • Where are you calling this function? Where exactly is this overload located (what namespace)? We need an MCVE. – David G Mar 19 '15 at 20:43
  • vector p; A sample call looks as simple as: LOG4CXX_TRACE(logger, "ack() " << p); I can't get this to work at the moment, but LOG4CXX_TRACE(logger, "ack() " << 1 << p); works just fine – Kelly Beard Mar 19 '15 at 20:46
  • Paste a small example program into your question that reproduces the error. This is still not enough. – David G Mar 19 '15 at 21:40
  • Adding the namespace {} block around my ostream operator causes this to compile and work correctly. The problem I'm having in my other source file must surely we some namespace confusion. I'll work on separating this code out into it's own file. I'll report my results. – Kelly Beard Mar 20 '15 at 15:22

0 Answers0