Dan*_*Dan 41 c++ foreach qt qlist
我是Qt的新手,并试图学习成语.
该foreach文件说:
Qt在进入foreach循环时自动获取容器的副本.如果在迭代时修改容器,则不会影响循环.
但它没有说明如何在迭代时删除元素foreach.我最好的猜测是这样的:
int idx = 0;
foreach (const Foo &foo, fooList) {
if (bad(foo)) {
fooList.removeAt(idx);
}
++idx;
}
Run Code Online (Sandbox Code Playgroud)
看起来很丑陋,不得不idx在循环外部(并且必须保持一个单独的循环计数器).
此外,我知道这是的,深层复制发生了.foreach是一个QList便宜的副本,但是一旦我删除一个元素会发生什么 - 是否仍然便宜或是否有昂贵的复制修改?
编辑:这似乎不是惯用的Qt.
for (int idx = 0; idx < fooList.size(); ) {
const Foo &foo = fooList[idx];
if (bad(foo)) {
fooList.removeAt(idx);
}
else ++idx;
}
Run Code Online (Sandbox Code Playgroud)
Igo*_*Oks 49
你应该更好地使用迭代器:
// Remove all odd numbers from a QList<int>
QMutableListIterator<int> i(list);
while (i.hasNext()) {
if (i.next() % 2 != 0)
i.remove();
}
Run Code Online (Sandbox Code Playgroud)
Mat*_*Mat 21
如果您根本不需要副本,请使用迭代器.就像是:
QList<yourtype>::iterator it = fooList.begin();
while (it != fooList.end()) {
if (bad(*it))
it = fooList.erase(it);
else
++it;
}
Run Code Online (Sandbox Code Playgroud)
(并确保你真的想要使用QList而不是QLinkedList.)
foreach想要遍历集合进行检查时非常好,但正如您所发现的,当您想要更改底层集合的结构(而不是存储在那里的值)时,很难说明.所以我在那种情况下避免它,仅仅因为我无法弄清楚它是否安全或者复制开销有多少.
ale*_*sdm 11
如果测试函数是可重入的,您还可以使用QtConcurrent删除"坏"元素:
#include <QtCore/QtConcurrentFilter>
...
QtConcurrent::blockingFilter(fooList, bad);
Run Code Online (Sandbox Code Playgroud)
或STL变体:
#include <algorithm>
...
fooList.erase(std::remove_if(fooList.begin(), fooList.end(), bad),
fooList.end());
Run Code Online (Sandbox Code Playgroud)