I've been playing with some c++ hello world stuff, and thought I'd get qt strings a whirl. Echoing and converting strings is fine, but endl seems to be special:
#include <QTextStream>
int main(int, char*[])
{
// Works, but is hacky (note: empty string):
// QTextStream(stdout) << "" << endl;
// Does not compile:
// QTextStream(stdout) << endl;
// Best? way (thanks to suy on #qt@freenode):
QTextStream out(stdout);
out << endl;
return 0;
}
So, why does a bare call to QString(out) << end; fail to compile? The compiler indicates that there's no conversion for the case, but why does it correctly convert with an empty string? Is this a bug in qt, or just how c++ looks up templates? Full compiler error below.
There's a gist, and in order to test:
mkdir qt
cd qt
wget https://gist.github.com/e12e/f79e9f0e66ee3600e0aa/raw/7ab8239060134601e93a0013706df638af0b3edf/qt.cpp
cat qt.cpp #Check what you're compiling ;-)
qmake -project
qmake -makefile
make
./qt # outputs empty line
Note that the gist as posted works (outputs a newline and exits), you need to change the comments around so that the line prefixed with "fails to compile" to get an error like:
g++ -c -m64 -pipe -O2 -Wall -W -D_REENTRANT -fPIE -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -I/usr/lib/x86_64-linux-gnu/qt5/mkspecs/linux-g++-64 -I. -I. -isystem /usr/include/x86_64-linux-gnu/qt5 -isystem /usr/include/x86_64-linux-gnu/qt5/QtGui -isystem /usr/include/x86_64-linux-gnu/qt5/QtCore -I. -o qt.o qt.cpp
qt.cpp: In function ‘int main(int, char**)’:
qt.cpp:7:23: error: ambiguous overload for ‘operator<<’ (operand types are ‘QTextStream’ and ‘QTextStream&(QTextStream&)’)
QTextStream(stdout) << endl;
^
qt.cpp:7:23: note: candidates are:
In file included from /usr/include/x86_64-linux-gnu/qt5/QtCore/QTextStream:1:0,
from qt.cpp:1:
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:175:18: note: QTextStream& QTextStream::operator<<(QChar) <near match>
QTextStream &operator<<(QChar ch);
^
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:175:18: note: no known conversion for argument 1 from ‘QTextStream&(QTextStream&)’ to ‘QChar’
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:176:18: note: QTextStream& QTextStream::operator<<(char) <near match>
QTextStream &operator<<(char ch);
^
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:176:18: note: no known conversion for argument 1 from ‘QTextStream&(QTextStream&)’ to ‘char’
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:177:18: note: QTextStream& QTextStream::operator<<(short int) <near match>
QTextStream &operator<<(signed short i);
^
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:177:18: note: no known conversion for argument 1 from ‘QTextStream&(QTextStream&)’ to ‘short int’
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:178:18: note: QTextStream& QTextStream::operator<<(short unsigned int) <near match>
QTextStream &operator<<(unsigned short i);
^
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:178:18: note: no known conversion for argument 1 from ‘QTextStream&(QTextStream&)’ to ‘short unsigned int’
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:179:18: note: QTextStream& QTextStream::operator<<(int) <near match>
QTextStream &operator<<(signed int i);
^
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:179:18: note: no known conversion for argument 1 from ‘QTextStream&(QTextStream&)’ to ‘int’
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:180:18: note: QTextStream& QTextStream::operator<<(unsigned int) <near match>
QTextStream &operator<<(unsigned int i);
^
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:180:18: note: no known conversion for argument 1 from ‘QTextStream&(QTextStream&)’ to ‘unsigned int’
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:181:18: note: QTextStream& QTextStream::operator<<(long int) <near match>
QTextStream &operator<<(signed long i);
^
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:181:18: note: no known conversion for argument 1 from ‘QTextStream&(QTextStream&)’ to ‘long int’
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:182:18: note: QTextStream& QTextStream::operator<<(long unsigned int) <near match>
QTextStream &operator<<(unsigned long i);
^
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:182:18: note: no known conversion for argument 1 from ‘QTextStream&(QTextStream&)’ to ‘long unsigned int’
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:183:18: note: QTextStream& QTextStream::operator<<(qlonglong) <near match>
QTextStream &operator<<(qlonglong i);
^
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:183:18: note: no known conversion for argument 1 from ‘QTextStream&(QTextStream&)’ to ‘qlonglong {aka long long int}’
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:184:18: note: QTextStream& QTextStream::operator<<(qulonglong) <near match>
QTextStream &operator<<(qulonglong i);
^
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:184:18: note: no known conversion for argument 1 from ‘QTextStream&(QTextStream&)’ to ‘qulonglong {aka long long unsigned int}’
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:191:18: note: QTextStream& QTextStream::operator<<(const void*) <near match>
QTextStream &operator<<(const void *ptr);
^
/usr/include/x86_64-linux-gnu/qt5/QtCore/qtextstream.h:191:18: note: no known conversion for argument 1 from ‘QTextStream&(QTextStream&)’ to ‘const void*’
make: *** [qt.o] Error 1
There's an overload for functions like endl:
QTextStream &operator<<(QTextStream &s, QTextStreamFunction f);
This takes a QTextStream by non-const lvalue reference. QTextStream(stdout) is a temporary, and temporaries cannot bind to those.
There's also a member function overload for const char *:
QTextStream &operator<<(const char *c);
Notice how this returns a reference (which will dangle once the full expression is done, but is fine as long as the result is used only in chained operators etc). This reference allows for the calling of the first mentioned overload, whereas the temporary does not.
Personally, I would choose your last option unless there's a better way I don't know of (I haven't used Qt). This option is similar to what the standard does with std::cout, but instead of being a global variable, you define it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With