以下面两行代码为例:
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
}
有人告诉我第二种方法更可取。为什么会这样呢?
当前回答
我总是使用数组索引,因为我的许多应用程序需要“显示缩略图图像”之类的东西。所以我写了这样的东西:
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;
}
}
其他回答
这两个实现都是正确的,但我更喜欢'for'循环。由于我们已经决定使用Vector容器而不是其他容器,因此使用索引将是最好的选择。对vector使用迭代器将失去将对象放在连续内存块中的好处,这有助于简化对它们的访问。
这是现代c++灌输过程的一部分。迭代器是迭代大多数容器的唯一方法,所以即使对向量也使用迭代器,只是为了让自己进入正确的心态。说真的,这是我这么做的唯一原因——我不认为我曾经用不同类型的容器替换过一个向量。 哇,三周之后,还是有人投反对票。我想开玩笑是不值得的。
我认为数组索引可读性更好。它与其他语言中使用的语法以及老式C数组所使用的语法相匹配。它也更简洁。如果你的编译器有任何好的地方,效率应该是一个洗涤,而且几乎没有任何情况下,它是重要的。
即便如此,我仍然发现自己经常对向量使用迭代器。我相信迭代器是一个重要的概念,所以我尽可能地推广它。
分离关注点
将迭代代码从循环的“核心”关注点中分离出来是非常好的。这几乎是一个设计决策。
实际上,通过索引迭代将您与容器的实现联系在一起。向容器请求开始和结束迭代器,使循环代码可用于其他容器类型。
同样,在std::for_each方法中,你告诉集合要做什么,而不是询问它的内部信息
0x标准将引入闭包,这将使这种方法更容易使用-看看例如Ruby的[1..6]的表达能力。每个{|i| print i;}……
性能
但是可能有一个被监督的问题是,使用for_each方法产生了一个并行迭代的机会——intel线程块可以将代码块分布在系统中的处理器数量上!
注意:在发现算法库,特别是foreach之后,我花了两三个月的时间写了非常小的“helper”操作符结构,这会让其他开发人员发疯。在这之后,我回到了一个实用的方法-小循环体不应该再有foreach了:)
关于迭代器的必读参考书是《扩展STL》。
GoF在迭代器模式的末尾有一小段话,讲的是这种迭代;它被称为“内部迭代器”。这里也看看。
索引需要一个额外的mul操作。例如,对于vector<int> v,编译器将v[i]转换为&v + sizeof(int) * i。
因为您没有将代码绑定到some_vector列表的特定实现。如果你使用数组下标,它必须是某种形式的数组;如果使用迭代器,则可以在任何列表实现上使用该代码。