使用迭代器获取向量索引

时间:2008-09-25 09:33:23

标签: c++ indexing vector iterator

当迭代向量的元素时,最好使用迭代器而不是索引(参见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
}

但是,可能需要在循环体中使用索引。考虑到性能和灵活性/可扩展性,在这种情况下,下列哪一项更可取?

  1. 恢复为索引循环
    std::vector vec;
    size_t i;
    for ( i = 0; i < vec.size(); ++i )
    {
       // use i
    }
    
  2. 计算偏移量
    std::vector vec;
    std::vector::iterator it;
    for ( it = vec.begin(); it != vec.end(); ++it )
    {
       size_t i = it - vec.begin(); 
       // use i
    }
    
  3. 使用std :: distance
    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
    }
    

7 个答案:

答案 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的自动..)