QMap::value возвращает ссылку на временную

Я хотел бы вернуть константную ссылку на значение QMap. Насколько я понимаю, QMap отличается тем, что если вы попытаетесь получить доступ к несуществующему ключу, он создаст значение с помощью конструктора по умолчанию и вернет его. Но если я все же правильно понимаю, ссылка будет временной и поэтому я получаю предупреждение.

У меня есть этот фрагмент кода:

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

Как видите, я уже убедился, что ключ что-то возвращает, я создаю объект в первый раз, когда он требуется, а затем сохраняю его в QMap для дальнейшего использования.

Несмотря на это, я все еще получаю предупреждение, что я должен изменить здесь, чтобы исправить поведение?

Изменить:

Вот как я определил indexes:

QMap<QListWidgetItem *, T> indexes;

Это предупреждение, которое я получаю:

В экземпляре «const T& SelectListDialog::getSelectionDesc(QListWidgetItem*) [с T = BackgroundDesc]»:

предупреждение: возвращается ссылка на временный [-Wreturn-local-addr]

вернуть indexes.value (элемент);


person Idle    schedule 10.01.2019    source источник
comment
Покажите нам точное предупреждение и объявление indexes?   -  person Holt    schedule 10.01.2019
comment
@Holt добавлен в OP   -  person Idle    schedule 10.01.2019


Ответы (1)


Согласно документации QMap::value():

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

Обратите внимание, что возвращаемый тип — const T, а не ссылка. Это означает, что return indexes.value(item) вернет копию значения из QMap, а не назначит ссылку. Как только область действия функции выходит из области действия, скопированный объект уничтожается — это временный объект. Это объясняет предупреждение о "ссылке на временное", которое вы получаете.

В вашем конкретном случае вместо этого используйте оператор подписки. . Неконстантная перегрузка возвращает ссылку на тип T. Из документов:

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

Вы правильно сказали, что

QMap отличается тем, что если вы попытаетесь получить доступ к несуществующему ключу, он создаст значение с помощью конструктора по умолчанию и вернет его.

Но поскольку вы уже проверяете, существует ли ключ item в вашем QMap, вы гарантируете, что ключ item существует. Таким образом, вы можете (должны) изменить свой оператор return на:

return indexes[item];

Обратите внимание, что для const QMaps оператор нижнего индекса по умолчанию будет перегруженным оператором:

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

То же, что и value().

Это также возвращает копию значения вместо ссылки. Но поскольку ваша карта неконстантна, эта перегрузка не используется.

person TrebledJ    schedule 10.01.2019
comment
Хорошо, это работает, большое спасибо, я действительно думал, что использование значения - это путь туда... - person Idle; 10.01.2019
comment
Ну, Qt рекомендует .value() в случае, если key не существует, и вы не хотите создавать еще один экземпляр ключ-значение. Но в этом случае вы уже создаете экземпляр пары "ключ-значение", даже если он еще не существует внутри карты. Таким образом, индекс - это путь. :-) - person TrebledJ; 10.01.2019
comment
Большое спасибо за объяснение - person Idle; 10.01.2019