Search code examples
c++operator-overloadingstream-operators

Overloaded << Operator in C++ not found


Here is what troubles me: I have an overloaded operator << in a header file FAPPDebug.h such as:

QTextStream& operator << (QTextStream& a, FAPPDebug& b);

and the implementation in FAPPDebug.cpp:

QTextStream& operator << (QTextStream& a, FAPPDebug& b)
{
    QString msg = *b.stream->ts.string(); // just take the message from b
    a << msg;
    return a;
}

and the corresponding function call:

QTextStream(stdout) << (debug() << "Quitting because application object is not set.");

regardless of how weird this looks, this compiles (and works!) under Windows with MSVC2010

debug() is just a macro to create a FAPPDebug object from the current location. Please note the extra set of () around (debug() << "...") without that it is not producing what I want.

On the other end under Linux with g++ 4.4 I get the following error:

MessageBroker.cpp:91: error: no match for ‘operator<<’ in ‘QTextStream(stdout, QFlags((QIODevice::OpenModeFlag)3u)) << ((FAPPDebug*)((FAPPDebug*)FAPPDebug(417, ((const char*)"MessageBroker.cpp"), ((const char*)(& PRETTY_FUNCTION)), (LogLevel)7u).FAPPDebug::operator<<(((const char*)"Module")))->FAPPDebug::operator<<(((const QString&)((const QString*)(& ModuleBase::getModuleDescription()())))))->FAPPDebug::operator<<(((const char*)"Quitting because application object is not set."))’ /usr/local/Trolltech/Qt-4.8.2/include/QtCore/qtextstream.h:184: note: candidates are: FAPPDebug.h:94: note: QTextStream& operator<<(QTextStream&, FAPPDebug&)

(There are a lot of candidates, I have just kept what is important)

I have modified the function call to be:

::operator << (QTextStream(stdout),  debug() << "Failed to schedule application startup.");

and I get the error message:

MessageBroker.cpp: In member function ‘bool MessageBroker::init(Application*, const QString&)’: MessageBroker.cpp:91: error: no matching function for call to ‘operator<<(QTextStream, FAPPDebug&)’ /usr/local/Trolltech/Qt-4.8.2/include/QtCore/qchar.h:396: note: candidates are: QDataStream& operator<<(QDataStream&, const QChar&) /home/ferenc/work/trunk/Core/Common/FAPPDebug.h:94: note:
QTextStream& operator<<(QTextStream&, FAPPDebug&)

so as you can see the correct function is found every time (yes, the FAPPDebug.h header is included in MessageBroker.cpp), but the "more standard compliant" compiler failed to use it. I have the feeling that this is a glitch in my comprehension of the standard somewhere, so I am asking for your help to find it.

EDIT: the operator is declared as friend in class FAPPDebug

EDIT2: The debug() is a macro, and is defined like:

#define debug() FAPPDebug(__LINE__, __FILE__, __PRETTY_FUNCTION__, LOG_DEBUG)

ie. it just created a FAPPDebug object with parameters indicating the current position.

Thanks! f.


Solution

  • I think the problem may be that your insertion operator accepts a reference (lvalue) as the first parameter, as expected, but you are trying to pass a rvalue created automatically from a constructor. Think about it, how do you expect an automatically created QTextStream(stdout) to live a sequence of calls of the type, QTextStream(stdout) << a << b << c. In truth, this is x << a then x << b then x << c. For it to live that happening in a single sentence I think both the first and the return must be const references, which is able to pin your rvalue. Or you may just declare a variable like QTextStream qout(stdout), and use qout instead.