如何从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());