以下面两行代码为例:

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
}

有人告诉我第二种方法更可取。为什么会这样呢?


当前回答

我不使用迭代器的原因与我不喜欢foreach-statements的原因相同。当有多个内部循环时,如果不记住所有的局部值和迭代器名称,就很难跟踪全局/成员变量。我发现有用的是在不同的情况下使用两组指标:

for(int i=0;i<anims.size();i++)
  for(int j=0;j<bones.size();j++)
  {
     int animIndex = i;
     int boneIndex = j;


     // in relatively short code I use indices i and j
     ... animation_matrices[i][j] ...

     // in long and complicated code I use indices animIndex and boneIndex
     ... animation_matrices[animIndex][boneIndex] ...


  }

例如,我甚至不想将“animation_matrices[I]”缩写为一些随机的“anim_matrix”-name -iterator,因为这样你就不能清楚地看到这个值来自哪个数组。

其他回答

已经有几个好观点了。我还有一些补充意见:

Assuming we are talking about the C++ standard library, "vector" implies a random access container that has the guarantees of C-array (random access, contiguos memory layout etc). If you had said 'some_container', many of the above answers would have been more accurate (container independence etc). To eliminate any dependencies on compiler optimization, you could move some_vector.size() out of the loop in the indexed code, like so: const size_t numElems = some_vector.size(); for (size_t i = 0; i Always pre-increment iterators and treat post-increments as exceptional cases.

for (some_iterator = some_vector.begin(); some_iterator != some_vector.end(); ++some_iterator){ //do stuff }

假设和可索引std::vector<>类似于容器,没有好的理由选择一个而不是另一个,按顺序遍历容器。如果必须频繁引用较旧或较新的元素索引,则使用索引版本更合适。

一般来说,使用迭代器是首选的,因为算法会使用它们,并且可以通过改变迭代器的类型来控制(并隐式记录)行为。数组位置可以用来代替迭代器,但是语法上的差异会很明显。

这是现代c++灌输过程的一部分。迭代器是迭代大多数容器的唯一方法,所以即使对向量也使用迭代器,只是为了让自己进入正确的心态。说真的,这是我这么做的唯一原因——我不认为我曾经用不同类型的容器替换过一个向量。 哇,三周之后,还是有人投反对票。我想开玩笑是不值得的。

我认为数组索引可读性更好。它与其他语言中使用的语法以及老式C数组所使用的语法相匹配。它也更简洁。如果你的编译器有任何好的地方,效率应该是一个洗涤,而且几乎没有任何情况下,它是重要的。

即便如此,我仍然发现自己经常对向量使用迭代器。我相信迭代器是一个重要的概念,所以我尽可能地推广它。

只有当vector.size()是一个快速操作时,第一种形式才有效。这对于向量是正确的,但是对于列表就不是这样了。另外,您计划在循环体中做什么?如果您计划访问元素,如

T elem = some_vector[i];

然后假设容器定义了operator[](std::size_t)。同样,这适用于vector容器,但不适用于其他容器。

迭代器的使用使您更接近容器独立性。您没有假设随机访问能力或快速size()操作,只是假设容器具有迭代器功能。

您可以通过使用标准算法进一步增强代码。根据你想要实现的目标,你可以选择使用std::for_each(), std::transform()等等。通过使用标准算法而不是显式循环,您可以避免重新发明轮子。您的代码可能更高效(如果选择了正确的算法)、正确和可重用。

假设some_vector是用链表实现的。然后,在第i个位置请求一个项需要执行i个操作来遍历节点列表。现在,如果您使用迭代器,一般来说,它将尽最大努力尽可能高效(在链表的情况下,它将维护一个指向当前节点的指针,并在每次迭代中推进它,只需要一个操作)。

所以它提供了两件事:

使用的抽象:你只想迭代一些元素,你不关心如何去做 性能

还没有人提到索引的一个优点是,当您向std::vector这样的连续容器添加索引时,它们不会失效,因此您可以在迭代期间向容器添加项。

这也可以用迭代器实现,但必须调用reserve(),因此需要知道要追加多少项。