以下面两行代码为例:
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
}
有人告诉我第二种方法更可取。为什么会这样呢?
以下面两行代码为例:
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
}
有人告诉我第二种方法更可取。为什么会这样呢?
当前回答
分离关注点
将迭代代码从循环的“核心”关注点中分离出来是非常好的。这几乎是一个设计决策。
实际上,通过索引迭代将您与容器的实现联系在一起。向容器请求开始和结束迭代器,使循环代码可用于其他容器类型。
同样,在std::for_each方法中,你告诉集合要做什么,而不是询问它的内部信息
0x标准将引入闭包,这将使这种方法更容易使用-看看例如Ruby的[1..6]的表达能力。每个{|i| print i;}……
性能
但是可能有一个被监督的问题是,使用for_each方法产生了一个并行迭代的机会——intel线程块可以将代码块分布在系统中的处理器数量上!
注意:在发现算法库,特别是foreach之后,我花了两三个月的时间写了非常小的“helper”操作符结构,这会让其他开发人员发疯。在这之后,我回到了一个实用的方法-小循环体不应该再有foreach了:)
关于迭代器的必读参考书是《扩展STL》。
GoF在迭代器模式的末尾有一小段话,讲的是这种迭代;它被称为“内部迭代器”。这里也看看。
其他回答
STL迭代器大部分都在那里,所以STL算法,比如sort,可以是容器独立的。
如果你只是想循环遍历一个向量中的所有项,只需使用索引循环样式。
对大多数人来说,它的输入更少,更容易解析。如果c++有一个简单的foreach循环,而不是过度使用模板魔法,那就太好了。
for( size_t i = 0; i < some_vector.size(); ++i )
{
T& rT = some_vector[i];
// now do something with rT
}
'
因为它更面向对象。如果你用一个索引迭代,你假设:
A)这些对象是有序的 B)这些对象可以通过索引获得 C)索引增量会影响每一项 D,指数从零开始
使用迭代器,你是在说“给我所有东西,这样我就可以使用它”,而不知道底层实现是什么。(在Java中,有些集合不能通过索引访问)
此外,使用迭代器,无需担心超出数组的边界。
第二种形式更准确地表示您正在做什么。在你的例子中,你并不关心i的值,你所需要的只是迭代器中的下一个元素。
假设some_vector是用链表实现的。然后,在第i个位置请求一个项需要执行i个操作来遍历节点列表。现在,如果您使用迭代器,一般来说,它将尽最大努力尽可能高效(在链表的情况下,它将维护一个指向当前节点的指针,并在每次迭代中推进它,只需要一个操作)。
所以它提供了两件事:
使用的抽象:你只想迭代一些元素,你不关心如何去做 性能
我总是使用数组索引,因为我的许多应用程序需要“显示缩略图图像”之类的东西。所以我写了这样的东西:
some_vector[0].left=0;
some_vector[0].top =0;<br>
for (int i = 1; i < some_vector.size(); i++)
{
some_vector[i].left = some_vector[i-1].width + some_vector[i-1].left;
if(i % 6 ==0)
{
some_vector[i].top = some_vector[i].top.height + some_vector[i].top;
some_vector[i].left = 0;
}
}