Question

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.

Was it helpful?

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.

OTHER TIPS

Shouldn't the second parameter to your operator<< be FAPPDebug const&? You can't initialize a non-const reference with a temporary, even if some compilers still fail to detect the error.

If you look closely, the functions which compiler see used and what you have defined aren't the same.

What it sees:

no matching function for call to ‘operator<<(QTextStream, ...

What it has defined

QTextStream& operator<<(QTextStream&, ...

It seems like temporary object couldn't be passed as non-const reference. So either change it to QTextStream const& or use rvalue reference.

EDIT: Oh well, I just understood that stream passed as first parameter can't really be const. Using rvalue reference or just catching by value, if it's possible, seems to me the only way to do it now. It's your (debug() ...) object that's causing the problem.

I had this problem, and it is a problem of any beginner in C++.

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

This is your declaration, but your usage is:

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

I assume you have your FAPPDEbug object having an operator that lets it use operator on const char pointer. so then this becomes this

QTextStream(stdout) << FAPPDebugObject; 

And you compiler wont find it in a case if FAPPDebugObject was not returned as a reference, because you are asking for a reference arg in the next operator.

I hope it made sense to you, or anyone looking for a solution.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top