以下面两行代码为例:

for (int i = 0; i < some_vector.size(); i++)
{
    //do stuff
}

这:

for (some_iterator = some_vector.begin(); some_iterator != some_vector.end();
    some_iterator++)
{
    //do stuff
}

有人告诉我第二种方法更可取。为什么会这样呢?


当前回答

比“告诉CPU做什么”(命令式)更好的是“告诉库你想要什么”(函数式)。

因此,你应该学习stl中的算法,而不是使用循环。

其他回答

在迭代过程中,您不需要知道要处理的项目的数量。你只需要item和迭代器就能很好地完成这些事情。

因为它更面向对象。如果你用一个索引迭代,你假设:

A)这些对象是有序的 B)这些对象可以通过索引获得 C)索引增量会影响每一项 D,指数从零开始

使用迭代器,你是在说“给我所有东西,这样我就可以使用它”,而不知道底层实现是什么。(在Java中,有些集合不能通过索引访问)

此外,使用迭代器,无需担心超出数组的边界。

分离关注点

将迭代代码从循环的“核心”关注点中分离出来是非常好的。这几乎是一个设计决策。

实际上,通过索引迭代将您与容器的实现联系在一起。向容器请求开始和结束迭代器,使循环代码可用于其他容器类型。

同样,在std::for_each方法中,你告诉集合要做什么,而不是询问它的内部信息

0x标准将引入闭包,这将使这种方法更容易使用-看看例如Ruby的[1..6]的表达能力。每个{|i| print i;}……

性能

但是可能有一个被监督的问题是,使用for_each方法产生了一个并行迭代的机会——intel线程块可以将代码块分布在系统中的处理器数量上!

注意:在发现算法库,特别是foreach之后,我花了两三个月的时间写了非常小的“helper”操作符结构,这会让其他开发人员发疯。在这之后,我回到了一个实用的方法-小循环体不应该再有foreach了:)

关于迭代器的必读参考书是《扩展STL》。

GoF在迭代器模式的末尾有一小段话,讲的是这种迭代;它被称为“内部迭代器”。这里也看看。

在对这个问题有了更多的了解之后,我意识到这有点过于简单化了。这个循环的区别是:

for (some_iterator = some_vector.begin(); some_iterator != some_vector.end();
    some_iterator++)
{
    //do stuff
}

这个循环:

for (int i = 0; i < some_vector.size(); i++)
{
    //do stuff
}

相当小。事实上,这样做循环的语法似乎越来越适合我:

while (it != end){
    //do stuff
    ++it;
}

迭代器确实解锁了一些相当强大的声明性特性,当与STL算法库结合使用时,您可以做一些非常酷的事情,这些事情超出了数组索引管理的范围。

还没有人提到索引的一个优点是,当您向std::vector这样的连续容器添加索引时,它们不会失效,因此您可以在迭代期间向容器添加项。

这也可以用迭代器实现,但必须调用reserve(),因此需要知道要追加多少项。