以下面两行代码为例:

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){…}。

其他回答

比“告诉CPU做什么”(命令式)更好的是“告诉库你想要什么”(函数式)。

因此,你应该学习stl中的算法,而不是使用循环。

如果要在迭代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;
    }
}

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

第二种形式更准确地表示您正在做什么。在你的例子中,你并不关心i的值,你所需要的只是迭代器中的下一个元素。

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

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

因为您没有将代码绑定到some_vector列表的特定实现。如果你使用数组下标,它必须是某种形式的数组;如果使用迭代器,则可以在任何列表实现上使用该代码。