2

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);

Community
  • 1
  • 1
Idle
  • 37
  • 2
  • 9

1 Answers1

5

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.

TrebledJ
  • 8,713
  • 7
  • 26
  • 48
  • Alright it is working, thanks a lot, i really thought using value was the way to go there... – Idle Jan 10 '19 at 18:05
  • Well, Qt recommends `.value()` in case `key` doesn't exist and you don't wish to create another key-value instance. But in this case, you're already creating the key-value instance even it doesn't exist inside the map yet. So subscript is the way to go. :-) – TrebledJ Jan 10 '19 at 18:09
  • Thanks a lot for the explanation – Idle Jan 10 '19 at 18:14