我不熟悉c++语言。我已经开始使用向量,并注意到在我看到的所有通过索引遍历向量的代码中,for循环的第一个参数总是基于向量的值。在Java中,我可以对数组列表做这样的事情:

for(int i=0; i < vector.size(); i++){
   vector[i].doSomething();
}

我在c++中看不到这个的原因是什么呢?这是不好的做法吗?


当前回答

使用迭代器有几个强有力的理由,这里提到了其中一些:

稍后切换容器不会使代码失效。

例如,如果从std::vector转换为std::list或std::set,则不能使用数值索引来获取包含的值。使用迭代器仍然有效。

无效迭代的运行时捕获

如果在循环中间修改容器,下次使用迭代器时,它将抛出一个无效的迭代器异常。

其他回答

 //different declaration type
    vector<int>v;  
    vector<int>v2(5,30); //size is 5 and fill up with 30
    vector<int>v3={10,20,30};
    
    //From C++11 and onwards
    for(auto itr:v2)
        cout<<"\n"<<itr;
     
     //(pre c++11)   
    for(auto itr=v3.begin(); itr !=v3.end(); itr++)
        cout<<"\n"<<*itr;

遍历vector最简洁的方法是通过迭代器:

for (auto it = begin (vector); it != end (vector); ++it) {
    it->doSomething ();
}

或(相当于上述)

for (auto & element : vector) {
    element.doSomething ();
}

在c++ 0x之前,必须将auto替换为迭代器类型,并使用成员函数而不是全局函数begin和end。

This probably is what you have seen. Compared to the approach you mention, the advantage is that you do not heavily depend on the type of vector. If you change vector to a different "collection-type" class, your code will probably still work. You can, however, do something similar in Java as well. There is not much difference conceptually; C++, however, uses templates to implement this (as compared to generics in Java); hence the approach will work for all types for which begin and end functions are defined, even for non-class types such as static arrays. See here: How does the range-based for work for plain arrays?

如果你使用

std::vector<std::reference_wrapper<std::string>> names{ };

不要忘记,当你在for循环中使用auto时,也要使用get,就像这样:

for (auto element in : names)
{
    element.get()//do something
}

在STL中,程序员使用迭代器遍历容器,因为迭代器是一个抽象概念,在所有标准容器中实现。例如,std::list根本没有操作符[]。

有什么原因让我在c++中看不到这个吗?这是不好的做法吗?

不。这不是一个不好的实践,但是下面的方法使您的代码具有一定的灵活性。

通常,在c++ 11之前,迭代容器元素的代码使用迭代器,类似于:

std::vector<int>::iterator it = vector.begin();

这是因为它使代码更加灵活。

所有标准库容器都支持并提供迭代器。如果在开发的后期需要切换到另一个容器,则不需要更改此代码。

注意:编写适用于所有可能的标准库容器的代码并不像看起来那么容易。