Qt foreach循环与使用for循环遍历QList的顺序问题

29
当使用foreach循环迭代QList<T>时,根据我进行的测试,返回的项与标准for循环中的项以相同的顺序返回。我的问题是,对于具有自然排序(如QListQVector)的容器,foreach是否总是按照索引数字顺序返回项目?例如,以下两种方式是否始终等效?
QList<T> list;

for( int i=0; i<list.count(); ++i )
{ 
    // process items in numerical order by index
    // do something with "list[i]";
}

foreach( T item, list )
{ 
    // will items always be processed in numerical order by index?
    // do something with "item";
}

你不能在列表上使用 [i] 运算符,但只能在表格(向量...)中使用,以便在内存上进行随机访问。此外,尝试使用 C++11 的 foreach 循环:(for(T& item : list) {/*some code */})。也许这可以帮助。 - Krozark
@Krozark 不是的,operator[] 运行良好。参见:http://qt-project.org/doc/qt-4.8/qlist.html#operator-5b-5d - Nikos C.
@NikosC。好的,但不使用STL。对于您的问题,最有效的方法是使用迭代器begin()和end()(我真的不知道foreach宏是做什么的...)。 - Krozark
2个回答

34
foreach宏(又称为Q_FOREACH)使用容器的begin()end()迭代器请求方法。因此,如果您的容器是QListQVector,那么您的示例将始终是等效的。您可以在这里查看foreach源代码。foreach宏并不完美,它会复制容器 - 因此,只能在支持隐式共享的容器上使用。如果有C++11的for( : ) {}循环,请使用它们,否则Boost有一个更好的替代品。

链接已失效。请避免在没有给出答案或摘录的情况下进行链接。 - David Zwart
@cmannett85,你能告诉我如何使用for ( : ) { }循环遍历QList吗?抱歉问一个8年前的问题。 - Denis Turgenev
@Freedom_Ben,你能告诉我如何使用 for(:) {} 循环 QList 吗? - Denis Turgenev
@cmanett85,我在我的项目中使用了数千个foreach循环,但看到你的回答后意识到转换成for(:){}可以带来巨大的性能提升。请帮忙,我有一个snippet.h文件并从那个文件复制了所有迭代,但不幸的是它是用foreach写的版本。 - Denis Turgenev
谢谢,@cmannett85,所以对于QList,foreach和for(:){}都不会复制容器吗? - Denis Turgenev
显示剩余3条评论

3
根据这里找到的信息,foreach比第一种方法慢很多,这表明它们并不等价。

4
你说得没错,但是你没有理解为什么。在那些测试中,第一个foreach测试之所以慢很多,是因为每次迭代都会创建一个QString的浅拷贝,而使用实际容器数据的const引用则使时间大致恢复到其他测试的水平,因为这样可以绕过浅拷贝。相反,使用一个int列表也会产生相同的效果。 - cmannett85

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接