Qt foreach 关键词

The foreach Keyword

注意: foreach 关键词是在 C++11 基于范围的循环存在之前引入的。新代码应优先使用 C++11 基于范围的循环。

foreach 关键词是 Qt 对 C++ 语言的一种特定扩展,它通过预处理器实现。

其语法是:foreach (变量, 容器) 语句。例如,下面是如何使用 foreach 来迭代一个QList<QString>

QList<QString> values;
...
QString str;
foreach (str, values)
    qDebug() << str;

使用 foreach 编写的代码比使用迭代器的等价代码要简短得多

QList<QString> values;
...
QListIterator<QString> i(values);
while (i.hasNext()) {
    QString s = i.next();
    qDebug() << s;
}

除非数据类型包含逗号(例如,std::pair<int, int>),否则可以在 foreach 语句中定义用于迭代的变量

QList<QString> values;
...
foreach (const QString &str, values)
    qDebug() << str;

像任何其他 C++ 循环结构一样,您可以在 foreach 循环的体中使用大括号,并且可以使用 break 来退出循环

QList<QString> values;
...
foreach (const QString &str, values) {
    if (str.isEmpty())
        break;
    qDebug() << str;
}

对于 QMapQHash,foreach 自动访问 (键,值) 对的值组件,因此不应在容器上调用 values()(它会生成不必要的副本,见下文)。如果您想要同时迭代键和值,可以使用迭代器(它们更快),或者您还可以获取键,并使用它们来获取值

QMap<QString, int> map;
...
foreach (const QString &str, map.keys())
    qDebug() << str << ':' << map.value(str);

对于多值映射

QMultiMap<QString, int> map;
...
foreach (const QString &str, map.uniqueKeys()) {
    foreach (int i, map.values(str))
        qDebug() << str << ':' << i;
}

Qt 在进入 foreach 循环时会自动复制容器。如果您在迭代过程中修改容器,则这不会影响循环。(如果您没有修改容器,复制仍然会发生,但得益于 隐式共享,复制非常快。)

由于 foreach 创建了容器的副本,因此使用非常量引用的变量不允许您修改原始容器。它只影响副本,这可能不是您想要的。

Qt 的 foreach 循环的另一种选择是 C++11 及更高版本中作为其一部分的基于范围的 for 循环。但是,请记住,基于范围的 for 可能会强制 Qt 容器 分离,而 foreach 不会。但是使用 foreach 总是复制容器,对于 STL 容器通常并不便宜。如果有疑问,请优先为 Qt 容器使用 foreach,为 STL 容器使用基于范围的 for。

您可以通过定义 QT_NO_FOREACH 宏来移除 Qt foreach 循环的可用性。

© 2024 Qt公司有限公司。本文档中包含的文档贡献版权归各所有者所有。本提供的文档根据自由软件基金会发布、版本为1.3的GNU自由文档许可协议许可。Qt及其相关标志是芬兰和/或世界其他地区的Qt公司有限公司的商标。所有其他商标均为其所有者的财产。