Domanda

I tried to overload QDebug::operator<< for std::string. I know that we can debug (using qDebug()) std::string objects using its std::string::c_str() function but I want to avoid typing .c_str each time.

Here is my attempt

#include <QDebug>
#include <string>

inline const QDebug& operator<< (const QDebug& qDebugObj, const std::string& str) {
    return qDebugObj << str.c_str();
}

int main()
{
     std::string s = "4444555";
     qDebug() << s;
}

This program produces segmentation fault. What is incorrect with this code?

Here is the stack:

#1  0x00000037c407a911 in malloc () from /lib64/libc.so.6
#2  0x00000037ca8bd09d in operator new(unsigned long) () from /usr/lib64/libstdc++.so.6
#3  0x00000037ca89c3c9 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) ()
   from /usr/lib64/libstdc++.so.6
#4  0x00000037ca89cde5 in ?? () from /usr/lib64/libstdc++.so.6
#5  0x00000037ca89cf33 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) () from /usr/lib64/libstdc++.so.6
#6  0x00000000004012ca in operator<< (qDebugObj=..., str="4444555") at main.cpp:5
È stato utile?

Soluzione

If you look at every overloaded output operator, you will see that none have a const qualifier. Which is your problem, you try to modify a constant object. Remove the const qualification of the qDebugObject and the return value.

You should have compiler warnings screaming about it, and if not then you need to enable more warnings (at least use -Wall when compiling with GCC/clang).


The actual problem, as answered by Mike Seymour in a comment, is that your overload will be called recursively until you get a stack overflow.

A way of bypassing that might be to convert the string to something else, like for example a QString:

return qDebugObj << QString::fromStdString(str);

Altri suggerimenti

In addition to your attempt to make an output stream const, you also failed to follow the instructions in the QT documentation

// with the fixed output operator
inline QDebug operator<<(QDebug dbg, const std::string& str)
{
    dbg.nospace() << QString::fromStdString(str);
    return dbg.space();
}

QT wants the output operator passed by copy (not by reference). There used to be a reason for that, but I cannot remember what it was.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top