c++qtqmap

QMap::value return reference to temporary


I would like to return a const reference to a QMap value. From what I can understand, QMap is special in that if you try to access a key that does not exist, it will create a value with the default constructor and return it. But if I still understand correctly, the reference will be temporary and therefore I get the warning.

I have this piece of code:

const T &getSelectionDesc(QListWidgetItem *item)
{
    if (!indexes.contains(item))
        indexes.insert(item, T(item->text()));
    return indexes.value(item);
}

As you can see, I've already made sure that the key returns something, I create the object the first time it is required and then save it in the QMap for ulterior uses.

Despite that, I still get the warning, what should I change here to correct the behavior?

Edit:

Here is how I've defined indexes:

QMap<QListWidgetItem *, T> indexes;

This is the warning I'm getting:

In instantiation of 'const T& SelectListDialog::getSelectionDesc(QListWidgetItem*) [with T = BackgroundDesc]':

warning: returning reference to temporary [-Wreturn-local-addr]

return indexes.value(item);


Solution

  • According to the documentation of QMap::value():

    const T QMap::value(const Key &key, const T &defaultValue = T()) const

    Note that the return type is const T and isn't a reference. This means that return indexes.value(item) will return a copy of the value from the QMap, and not assign a reference. As soon as function scope is exited, the copied object is destroyed -- it is a temporary object. This explains the "reference to temporary" warning you're getting.

    In your particular case, use the subscript operator instead. The non-const overload returns a reference to type T. From the docs:

    T &QMap::operator[](const Key &key)

    You've stated correctly that

    QMap is special in that if you try to access a key that does not exist, it will create a value with the default constructor and return it.

    But since you're already checking to make sure that the key item exists in your QMap, you guarantee that the key item exists. Thus you could (should) change your return statement to:

    return indexes[item];
    

    Note that for const QMaps, the subscript operator would default to the overloaded operator:

    const T QMap::operator[](const Key &key) const

    Same as value().

    This also returns a copy of the value instead of a reference. But as your map is non-const, this overload is not used.