Search code examples
qtrvalue-referenceqstringqvariantstdmove

Passing rvalue reference to QVariant does not work with QString


I am trying to return a rvalue reference from a function to a QVariant. It works for bool and int, but when I pass a string I get an 'invalid' QVariant.

My function:

QVariant &&AudioSettings::getValueFromTable(const QString &name)
{
    QSqlQuery query(_messengerDB);
    auto queryStr = QString("SELECT %1 FROM user_audio WHERE id = 1;").arg(name);
    if(query.exec(queryStr)){

        if(query.next()){
            qDebug() << "AudioSettings::getValueFromTable" << query.value(0);  //here I have a correct QString value => QVariant(QString, "Głośniki (USB Audio CODEC )")
            return std::move(query.value(0));

        } else {
            qDebug() << "AudioSettings::setValueToTable : No data for '" << queryStr << "'";
            return QVariant();
        }

    } else {
        qDebug()<<"AudioSettings::setValueToTable : Error during getting " << name << " form table user_audio.";
        qDebug() << query.lastQuery();
        qDebug() << query.lastError();
    }
    return QVariant();
}

when I call:

QString &&AudioSettings::getAudioOut()
{
    auto value = getValueFromTable("audio_out");  //here I get an invalid QVariant
    return value.isNull() ? QString() : value.toString(); 
}

What works is:

int AudioSettings::getRingtoneType()  //EDIT
{
    auto value = getValueFromTable("ringtone_type");  //EDIT, I am getting a QVariant with an int inside
    return value.isNull() ? 0 : value.toInt();
}

Does anyone know why?


Solution

  • As stated in the comments, you are returning a dangling reference. So you have undefined behavior and anything can happen.

    In the case that works, the QVariant holds an integer. My guess is that you are just lucky that the memory that holds the int has not be rewritten (or freed).

    For the QString your luck runs out, the actual content is not stored in the QString object, but it is stored on the heap and has been released once the function has returned. All that is left is an empty/null QString.

    Solution: return the QVariant by value.