基于范围的 for 循环与常规迭代器 for 循环

Posted

技术标签:

【中文标题】基于范围的 for 循环与常规迭代器 for 循环【英文标题】:range based for loop vs regular iterator for loop 【发布时间】:2015-04-11 13:07:44 【问题描述】:

考虑以下代码示例:

#include<iostream>
#include<vector>
#include<typeinfo>

int main()
    std::vector<int> v = 1 ,2,4;
    for(auto &i:v)  std::cout<<typeid(i).name();
    for(auto k = v.begin(); k!=v.end();++k) std::cout<<typeid(k).name();
    return 0;

第一个循环表示基于范围的 for 循环,第二个循环是带有迭代器的常规 for 循环。我经常使用常规循环,根据我的经验,auto k 是迭代器类型,而基于范围的循环的类型是 auto i 作为 int。上述程序的输出是:

i & N9__gnu_cxx17__normal_iteratorIPiSt6vectorIiSaIiEEEE

对于像向量这样的集合(在某处提到)上基于范围的循环,这是正常的行为吗?因为有人(比如我)会假设基于范围的 for 循环只是常规 for 循环的简写。

【问题讨论】:

这是设计的。基于范围的for 循环为您提供了元素。这是一个足够好的答案吗? 必须有理由将它们设计成这样,我看不到。有参考吗? 请注意,这两个循环并不完全等效:您的显式基于范围的循环每次都会评估end(),因此可以适应向量的结构变化(只要它们不失效k)。基于范围的循环仅在开始时评估end(),因此您最好将向量的结构单独留在内部。因此,没有为您提供更改该结构的方法(即迭代器),而仅提供访问/更改值的方法是有道理的。 @celtschk 感谢您的洞察力:)。我当然不知道。 typeid::name 返回值是实现定义的。 ***.com/questions/4465872/… 【参考方案1】:

答案就是 Magnus 已经说过的:是的,这是正常行为。范围循环适用于我们有兴趣检查集合中的每个项目(除非我们更早爆发)并且对容器本身做任何事情不感兴趣的情况。就像已经说过的那样,范围循环以这种方式优化,例如它确实只计算了一次完成条件。在我看来,这是对 c++ 中各种循环选项的一个非常好的和受欢迎的补充,因为我们确实经常面临这种非常确切的情况:我们得到一个容器,并且有兴趣在 const 或非常规时尚。

【讨论】:

【参考方案2】:

基于范围的 for 循环将给出容器元素。

例如:

vectorv5,7,10;

for(auto i:v)

cout

【讨论】:

以上是关于基于范围的 for 循环与常规迭代器 for 循环的主要内容,如果未能解决你的问题,请参考以下文章

C++11 反向基于范围的 for 循环

C++11 反向基于范围的 for 循环

在基于范围的 for 循环期间插入 std::list 的后面

C++基于范围的for循环详解

r值上基于范围的for循环

我可以使用基于范围的 for 循环轻松迭代地图的值吗?