Qt:是否可以在使用 foreach 宏进行迭代时删除 QList 元素?

2021-12-26 00:00:00 qt foreach c++ qlist

我是 Qt 的新手,正在尝试学习习语.

I'm new to Qt and trying to learn the idioms.

foreach 文档 说:

Qt 在进入 foreach 循环时自动获取容器的副本.如果您在迭代时修改容器,则不会影响循环.

Qt automatically takes a copy of the container when it enters a foreach loop. If you modify the container as you are iterating, that won't affect the loop.

但它没有说明如何在使用 foreach 进行迭代时删除元素.我最好的猜测是这样的:

But it doesn't say how to remove an element while iterating with foreach. My best guess is something like:

int idx = 0;
foreach (const Foo &foo, fooList) {
  if (bad(foo)) {
    fooList.removeAt(idx);
  }
  ++idx;
}

必须将 idx 范围限定在循环之外(并且必须维护一个单独的循环计数器),这看起来很丑陋.

Seems ugly to have to scope idx outside the loop (and to have to maintain a separate loop counter at all).

另外,我知道 foreach 制作了 QList 的副本,这很便宜,但是一旦我删除一个元素会发生什么――仍然是便宜还是正在进行昂贵的复制修改? 是的,发生深度复制.

Also, I know that foreach makes a copy of the QList, which is cheap, but what happens once I remove an element -- is that still cheap or is there an expensive copy-on-modify going on? Yes, deep copy happens.

这似乎也不是惯用的 Qt.

EDIT : This doesn't seem like idiomatic Qt either.

for (int idx = 0; idx < fooList.size(); ) {
  const Foo &foo = fooList[idx];
  if (bad(foo)) {
    fooList.removeAt(idx);
  }
  else ++idx;
}

推荐答案

你最好为此使用迭代器:

// Remove all odd numbers from a QList<int> 
QMutableListIterator<int> i(list);
while (i.hasNext()) {
    if (i.next() % 2 != 0)
        i.remove();
}

相关文章