当迭代向量的元素时,最好使用迭代器而不是索引(参见Why use iterators instead of array indices?)。
std::vector<T> vec;
std::vector<T>::iterator it;
for ( it = vec.begin(); it != vec.end(); ++it )
{
// do work
}
但是,可能需要在循环体中使用索引。考虑到性能和灵活性/可扩展性,在这种情况下,下列哪一项更可取?
std::vector vec; size_t i; for ( i = 0; i < vec.size(); ++i ) { // use i }
std::vector vec; std::vector::iterator it; for ( it = vec.begin(); it != vec.end(); ++it ) { size_t i = it - vec.begin(); // use i }
std::vector vec; std::vector::iterator it; for ( it = vec.begin(); it != vec.end(); ++it ) { size_t i = std::distance( vec.begin(), it ); // use i }
答案 0 :(得分:13)
如果您计划专门使用向量,则可能需要切换回索引循环,因为它比迭代器循环更清楚地传达您的意图。但是,如果将来程序的演变可能导致容器的更改,则应该坚持使用迭代器并使用std :: distance,这可以保证与所有标准迭代器一起使用。
答案 1 :(得分:8)
使用std :: distance更通用,因为它适用于所有迭代器,而不仅仅是随机访问迭代器。在随机访问迭代器的情况下它应该和它一样快 - vec.begin()。
它 - vec.begin()基本上是指针算法。
答案 2 :(得分:6)
std::distance(vec.begin(), it)
会指向it
指向的索引,假设它指向vec
。
卡尔
答案 3 :(得分:4)
恢复索引循环。
基本上在90%的情况下,迭代器是优越的,这是10%中的一个。通过使用迭代器,您将使代码更复杂,因此更难以理解,因为首先使用迭代器的完整原因是为了简化代码。
答案 4 :(得分:1)
您缺少一个解决方案:在需要时保留索引,但不要将其用作循环条件。也适用于列表,成本(每个循环)是O(n)和额外的寄存器。
答案 5 :(得分:0)
为了将来的发展原因,我总是倾向于使用迭代器。
在上面的例子中,如果您决定将std :: vector替换为std :: set(可能需要一个唯一的元素集合),使用迭代器和distance()将继续工作。
我非常确定任何性能问题都会被优化到可以忽略不计的程度。
答案 6 :(得分:0)
对于向量,我总是使用整数方法。向量中的每个索引与数组查找的速度相同。如果我将要使用该值很多,为方便起见,我会创建一个引用。
矢量迭代器在理论上可能比索引略快,因为它们使用指针算法迭代列表。但是,通常我发现可读性值得最小的运行时差异。
我将迭代器用于其他容器类型,有时候当你不需要循环变量时。但是如果你需要循环变量,除了让你的循环更难输入外,你什么都不做。 (我等不及c ++ 0x的自动..)