5

当迭代向量的元素时,最好使用迭代器而不是索引(请参阅为什么使用迭代器而不是数组索引?)。

std::vector<T> vec;
std::vector<T>::iterator it;
for ( it = vec.begin(); it != vec.end(); ++it )
{
   // do work
}

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

  1. 恢复到索引循环
    标准::向量向量;
    尺寸_t我;
    对于 ( i = 0; i < vec.size(); ++i )
    {
       // 使用我
    }
    
  2. 计算偏移量
    标准::向量向量;
    std::vector::iterator it;
    对于 (它 = vec.begin(); 它!= vec.end(); ++it)
    {
       size_t i = 它 - vec.begin();
       // 使用我
    }
    
  3. 使用 std::distance
    标准::向量向量;
    std::vector::iterator it;
    对于 (它 = vec.begin(); 它!= vec.end(); ++it)
    {
       size_t i = std::distance(vec.begin(), it);
       // 使用我
    }
    
4

7 回答 7

13

如果您打算仅使用向量,则可能需要切换回索引循环,因为它比迭代器循环更清楚地传达了您的意图。但是,如果您的程序在未来的演变可能导致容器的变化,您应该坚持使用迭代器并使用 std::distance,它保证可以与所有标准迭代器一起使用。

于 2008-09-25T09:59:47.937 回答
8

使用 std::distance 更通用一点,因为它适用于所有迭代器,而不仅仅是随机访问迭代器。它应该和它一样快 - vec.begin() 在随机访问迭代器的情况下。

它 - vec.begin() 基本上是指针算术。

于 2008-09-25T09:36:35.447 回答
6

std::distance(vec.begin(), it)假设it它指向vec.

卡尔

于 2008-09-25T14:07:08.760 回答
4

恢复到索引循环。

基本上在 90% 的情况下,迭代器是优越的,这是 10% 的情况之一。通过使用迭代器,您会使代码更复杂,因此更难理解,而使用迭代器的全部原因首先是为了简化代码。

于 2008-09-25T09:37:56.897 回答
1

您缺少一个解决方案:保留索引以备不时之需,但不要将其用作循环条件。也适用于列表,并且成本(每个循环)是 O(n) 和一个额外的寄存器。

于 2008-09-25T11:42:24.787 回答
0

出于未来发展的原因,我总是倾向于使用迭代器。

在上面的示例中,如果您可能决定将 std::vector 替换为 std::set (可能您需要一个唯一的元素集合),使用迭代器和 distance() 将继续有效。

我很确定任何性能问题都会被优化到可以忽略不计的程度。

于 2008-09-25T13:16:19.570 回答
0

对于向量,我总是使用整数方法。向量中的每个索引与数组查找的速度相同。如果我要大量使用该值,我会为它创建一个引用,以方便起见。

理论上,向量迭代器可能比索引稍快,因为它们使用指针算法来遍历列表。但是,通常我发现可读性值得最小的运行时差异。

I use iterators for other container types, and sometimes when you don't need the loop variable. But if you need the loop variable, you're not doing anything except making your loop harder to type. (I cannot wait for c++0x's auto..)

于 2008-09-25T16:11:29.897 回答