Log4cxx
  1. Log4cxx
  2. LOGCXX-150

logstream's operator<< declared in the wrong namespace

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 0.10.0
    • Fix Version/s: 0.10.0
    • Component/s: None
    • Labels:
      None
    • Environment:
      FC4 - g++ (GCC) 4.0.2 20051125

      Description

      This is one of those strange nuances of C++ (or maybe just GCC). logstream's << operators don't work from within a namespace that has operator<< defined. For example:

      #include <log4cxx/logger.h>
      #include <log4cxx/stream.h>
      #include <ostream>

      namespace foo
      {
      class Bar

      { void fn(); }

      ;

      std::ostream &operator<<(std::ostream &o, Bar const &b)

      { return o << "Bar"; }

      }

      using namespace foo;

      namespace
      {
      log4cxx::LoggerPtr logger(log4cxx::Logger::getLogger("foo"));
      log4cxx::logstream lout(logger, log4cxx::Level::DEBUG);
      }

      void Bar::fn()
      {
      lout << "hi" << LOG4CXX_ENDMSG;
      }

      Compiles with the following error:
      g++ -c -o log4cxx-ns.o log4cxx-ns.cpp
      log4cxx-ns.cpp: In member function 'void foo::Bar::fn()':
      log4cxx-ns.cpp:29: error: no match for 'operator<<' in '<unnamed>::lout << "hi"'
      log4cxx-ns.cpp:12: note: candidates are: std::ostream& foo::operator<<(std::ostream&, const foo::Bar&)

      For the Koenig lookup to work properly, the operator<< functions need to be defined in the log4cxx namespace.

        Activity

        Hide
        David M. Lee added a comment -

        fix to define logstream's operator<< in the log4cxx namespace

        Show
        David M. Lee added a comment - fix to define logstream's operator<< in the log4cxx namespace
        Hide
        Curt Arnold added a comment -

        Required a bit of a balancing act. The best place to put the templated insertion operators is within the scope of the logstream class, however VC6 (but not VC7 and later) will fail to compile the code giving either internal compiler errors or ambiguity errors. Placing the template at global scope will work with VC6, but runs into this issue which does not occur when the operator is at class scope.

        To resolve the issue:

        added a LOG4CXX_USE_GLOBAL_SCOPE_TEMPLATE macro that is set to 1 on VC6
        If not set, class-scope templates are used
        If set, global-scope templates are used
        Added your sample code to the end of streamtestcase.cpp wrapped in #if !LOG4CXX_USE_GLOBAL_SCOPE_TEMPLATE.

        Show
        Curt Arnold added a comment - Required a bit of a balancing act. The best place to put the templated insertion operators is within the scope of the logstream class, however VC6 (but not VC7 and later) will fail to compile the code giving either internal compiler errors or ambiguity errors. Placing the template at global scope will work with VC6, but runs into this issue which does not occur when the operator is at class scope. To resolve the issue: added a LOG4CXX_USE_GLOBAL_SCOPE_TEMPLATE macro that is set to 1 on VC6 If not set, class-scope templates are used If set, global-scope templates are used Added your sample code to the end of streamtestcase.cpp wrapped in #if !LOG4CXX_USE_GLOBAL_SCOPE_TEMPLATE.

          People

          • Assignee:
            Curt Arnold
            Reporter:
            David M. Lee
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development