Overriding QDebug& operator<<



  • Hi all,
    In Qt 5.1 , I have problems overriding QDebug& operator<<
    The following program works fine

    @
    #include <QtCore>

    class CData1 {
    public:
    CData1(int i=6,double d=3.14,QString s="Ni Hao"):i1(i),d1(d),s1(s) {}
    int i1;
    double d1;
    QString s1;
    friend QDebug& operator<< (QDebug&,const CData1& );
    };

    QDebug& operator<<(QDebug& dbg, const CData1& d){
    dbg.nospace() << "[" << d.i1 << ";"<< d.d1 << ";" << d.s1 << "]" ;
    return dbg.space();
    }

    int main() {
    CData1 d1;
    qDebug() << "" << d1;
    }

    @

    … and displays in the console : [6;3.14;”Ni Hao”]

    But in main() , when I replace

    @
    qDebug() << "" << d1;
    @

    by
    @
    qDebug() << d1;
    @

    I have the following compilation error :
    @
    D:\Source\Cpp\qt5\tpQDebug1\main.cpp:20: error: no match for 'operator<<' (operand types are 'QDebug' and 'CData1')
    @

    Thanks in advance for your help or comments

    Gilles



  • Not references to QDebug
    @
    QDebug operator<<(QDebug dbg, const CData1& d){
    ...
    }
    @



  • QDebug is already included in <QtCore>
    and the version with :
    @
    qDebug() << "" << d1;
    @

    compiles and works.

    For me, it looks like a Qt bug....


  • Moderators



  • I got it this time. ChrisW67 and koahnig, thanks a million.

    I have another question if you don't mind . How would you suggest to get rid of the LF in this case?

    I know that the LF or CR is added when the QDebug object is destroyed.

    Using a message handler does not seem to work as the qInstallMessageHandler function accepts only function with the following signature :
    @
    msgHandler1(QtMsgType , const QMessageLogContext &, const QString &)
    @

    So I can't pass my type CData1 to the message handler. I can't pass only QString.

    Is there any solution to display CData1 without LF using qDebug() ?


  • Moderators

    There is "another post on this":http://qt-project.org/forums/viewthread/21334/ Respectively, it has been added also as "doc note to QDebug":http://qt-project.org/doc/qt-5.0/qtcore/qdebug.html . Check the very last entry. If I understand correctly your question, this might solve your problem.

    Otherwise, the message handler is general and not restricted to QString output. You can use the handler to redirect your output to anywhere. QDebug does the conversion of all your output to QString.



  • Hi, this is a pure C++ problem, and the real reason is that:

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

    You can try to play with following code:

    @
    class CData1 {
    public:
    CData1(int i=6,double d=3.14,QString s="Ni Hao"):i1(i),d1(d),s1(s) {}
    int i1;
    double d1;
    QString s1;

    CData1 &ref() {return *this;}
    

    };

    void test(CData1 &)
    {
    }

    int main()
    {
    test(CData1().ref()); //Compile successful
    //test(CData1()); //Can not be compiled.
    return 0;
    }
    @

    And what you confused is following lines

    @
    operator <<(QDebug(QtDebugMsg).operator <<(""), d1); //Compile successful
    operator <<(QDebug(QtDebugMsg), d1); //Can not be compiled.
    @



  • Thanks koahnig, I almost got the big picture now.

    My tests just showed that the message handler is called only when the QDebug instance is suppressed.
    Is there a kind of "flush" to display data with the message handler before the suppression of QDebug. With this last feature, all my needs would be met I guess.



  • QTextStream is used inside of QDebug. When QDebug destroyed, the string contained in this QTextStream will be output. That's why qDebug() return a temporary object.

    While std::cout is a Global stream object, so flush is needed.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.