如何从QList中删除元素,而使用foreach迭代呢?

我是Qt新手,想学习这些成语。

foreach文档说:

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

但是它并没有说如何在用foreach迭代的时候去除一个元素。 我最好的猜测是这样的:

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

似乎丑陋必须将范围外的idx循环(并必须维护一个单独的循环计数器)。

另外,我知道foreach制作了一个QList的副本,这个版本很便宜,但是一旦我删除了一个元素,会发生什么呢?它还是很便宜的,还是会有昂贵的copy-on-modify呢? 是的, 深层复制发生 。

编辑:这似乎并不像地道的Qt要么。

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

如果你不想要一个副本,使用迭代器。 就像是:

 QList<yourtype>::iterator it = fooList.begin(); while (it != fooList.end()) { if (bad(*it)) it = fooList.erase(it); else ++it; } 

(并确保你真的想使用QList而不是QLinkedList 。)

当你想遍历一个集合进行检查时, foreach是非常好的,但是正如你所发现的那样,当你想要改变底层集合的结构(而不​​是存储在那里的值)时,很难推断。 所以我避免在这种情况下,只是因为我不知道是否安全或多less复制开销发生。

如果testing函数是可重入的,您也可以使用QtConcurrent来删除“坏”元素:

 #include <QtCore/QtConcurrentFilter> ... QtConcurrent::blockingFilter(fooList, bad); 

或STL变体:

 #include <algorithm> ... fooList.erase(std::remove_if(fooList.begin(), fooList.end(), bad), fooList.end());