以下面两行代码为例:

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
}

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


当前回答

如果你可以访问c++ 11的特性,那么你也可以使用一个基于范围的for循环来迭代你的vector(或任何其他容器),如下所示:

for (auto &item : some_vector)
{
     //do stuff
}

这个循环的好处是,您可以直接通过item变量访问vector的元素,而不会有搞乱索引或在解引用迭代器时出错的风险。此外,占位符auto可以防止您重复容器元素的类型, 这使您更接近于容器无关的解决方案。

注:

如果您需要循环中的元素索引,并且容器中存在操作符[](并且对您来说足够快),那么最好采用第一种方法。 基于范围的for循环不能用于在容器中添加/删除元素。如果你想这样做,那么最好坚持布莱恩·马修斯给出的解决方案。 如果你不想改变容器中的元素,那么你应该如下所示使用关键字const: for (auto const &item: some_vector){…}。

其他回答

在迭代过程中,您不需要知道要处理的项目的数量。你只需要item和迭代器就能很好地完成这些事情。

除了所有其他优秀的答案之外……Int对向量来说可能不够大。相反,如果你想使用索引,使用size_type为你的容器:

for (std::vector<Foo>::size_type i = 0; i < myvector.size(); ++i)
{
    Foo& this_foo = myvector[i];
    // Do stuff with this_foo
}

容器独立性

因为它更面向对象。如果你用一个索引迭代,你假设:

A)这些对象是有序的 B)这些对象可以通过索引获得 C)索引增量会影响每一项 D,指数从零开始

使用迭代器,你是在说“给我所有东西,这样我就可以使用它”,而不知道底层实现是什么。(在Java中,有些集合不能通过索引访问)

此外,使用迭代器,无需担心超出数组的边界。

如果要在迭代vector时向其添加/删除项,则可能需要使用迭代器。

some_iterator = some_vector.begin(); 
while (some_iterator != some_vector.end())
{
    if (/* some condition */)
    {
        some_iterator = some_vector.erase(some_iterator);
        // some_iterator now positioned at the element after the deleted element
    }
    else
    {
        if (/* some other condition */)
        {
            some_iterator = some_vector.insert(some_iterator, some_new_value);
            // some_iterator now positioned at new element
        }
        ++some_iterator;
    }
}

如果使用索引,则必须在数组中上下移动项以处理插入和删除。