我应该在基于 C++11 范围的 QHash::keys() 上使用 qAsConst

Posted

技术标签:

【中文标题】我应该在基于 C++11 范围的 QHash::keys() 上使用 qAsConst【英文标题】:Should I use qAsConst on QHash::keys() in a C++11 range-based for 【发布时间】:2017-09-13 08:21:40 【问题描述】:

在 KDAB 的这篇文章 Goodbye, Q_FOREACH 中,他们警告说基于范围的 for 可能会导致 Qt 容器分离。 也可以在这里查看:Using C++11 range-based for loop correctly in Qt

我知道for 会导致分离,因为如果容器不是 const,它会调用一些非常量迭代器。QHash::keys()的返回值是一样的吗?keys() 函数是 const 所以我的地图不会分离,但是返回值是按值传递的,所以我要复制 QList 两次吗?

那么,我应该这样循环吗?

for(auto key : qAsConst(map.keys())) 
    // do something with key or map.value(key)

【问题讨论】:

【参考方案1】:

不,它甚至无法编译(Qt5.9 - MSVC 2015):

QMap<QString, int> map;
for(auto key : qAsConst(map.keys())) 
    // do something with key or map.value(key)

错误:使用已删除的函数 'void qAsConst(const T&&) [with T = QList]'

【讨论】:

由于(可能的)所有权问题,该函数因右值而被删除。如文章中所述,您可以简单地将右值分配给 const 变量,即auto const keys = map.keys(),然后在 for 范围内使用它。【参考方案2】:

创建一个临时的 keys() 容器只是为了对其进行迭代,无论如何都是一个非常缓慢的解决方案。更喜欢使用迭代器。

【讨论】:

以上是关于我应该在基于 C++11 范围的 QHash::keys() 上使用 qAsConst的主要内容,如果未能解决你的问题,请参考以下文章

基于范围的循环:自动更改 C++11 中的含义

如何让 C++0x / C++11 风格的基于范围的 for 循环与 clang 一起使用?

C++11 反向基于范围的 for 循环

C++11 反向基于范围的 for 循环

在 Qt 中正确使用 C++11 基于范围的 for 循环

C++11 基于范围的for循环