1+1=10

记记笔记,放松一下...

left shift operator overloading for QDebug()

Consider that we have create a custom type:

1
2
3
4
5
6
struct Point
{
Point(int x, int y):x(x),y(y){}
int x;
int y;
};

If we want to make it work with qDebug(), we need to implement a streaming operator:

1
QDebug operator<<(QDebug dbg, const Point &p)

But, wait ...

When we using pure c++, what we do is:

1
ostream &operator<<(ostream &out, const Point &p)

Why QDebug object is passed by value instead of reference?

qDebug() vs. std::cout

In first glance, qDebug() is very similiar to std::cout.

1
2
qDebug()<<"From Qt qDebug()";
std::cout<<"From C++ std::cout"<<std::endl;

However, each time we call qDebug(), a new QDebug object will be created.

1
QDebug qDebug() { return QDebug(QtDebugMsg); }

while std::cout is a global std::ostream object, the header file iostream is more or less like this:

1
2
3
4
5
namespace std
{
    extern ostream cout;
    static ios_base::Init __ioinit;
}

Why reference doesn't work for QDebug

We know that,

1
qDebug() << Point(1,2);

can be wrriten as:

1
QDebug(QtDebugMsg) << Point(1,2);

Which can also be wrriten as:

1
operator <<(QDebug(QtDebugMsg), Point(1,2));

As we can see, a temporary QDebug object is passed to the function in above statements.

But in C++, we know that,

A temporary cannot be bound to a non-const reference.

That why

1
QDebug operator<<(QDebug dbg, const Point &p)

should be used instead of

1
QDebug & operator<<(QDebug &dbg, const Point &p)

Problem?

Some one complain that, though

1
QDebug & operator<<(QDebug &dbg, const Point &p)

doesn't work for qDebug()<<Point(1,2);, but it indeed works for qDebug()<<""<<Point(1,2);. Why?

The latter statement can be re-written as

1
operator <<(QDebug(QtDebugMsg).operator <<(""), Point(1,2));

and note that, QDebug has provided the member function for type char *:

1
QDebug & QDebug::operator<<(const char * s);

in which a reference to current QDebug object is return.

So C++ compiler will be happy with this now.

Qt Qt