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

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

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


当前回答

这是一个更简单的方法来迭代和打印值在向量。

for(int x: A) // for integer x in vector A
    cout<< x <<" "; 

其他回答

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

 //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;

使用auto操作符真的很容易使用,因为人们不必担心数据类型和向量或任何其他数据结构的大小

使用auto和for循环迭代vector

vector<int> vec = {1,2,3,4,5}

for(auto itr : vec)
    cout << itr << " ";

输出:

1 2 3 4 5

您还可以使用此方法迭代集和列表。使用auto会自动检测模板中使用的数据类型,并允许您使用它。 所以,即使我们有一个string或char类型的向量,同样的语法也可以工作得很好

令我惊讶的是,没有人提到遍历具有整数索引的数组会很容易通过下标具有错误索引的数组来编写错误代码。例如,如果使用i和j作为下标嵌套循环,则可能错误地将数组下标为j而不是i,从而在程序中引入错误。

相比之下,这里列出的其他形式,即基于范围的for循环和迭代器,更不容易出错。该语言的语义和编译器的类型检查机制将防止您意外地使用错误的索引访问数组。

不要忘记具有const正确性的例子-循环可以修改元素。这里的许多示例都没有这样做,应该使用cont迭代器。这里我们假设

class T {
  public:
    T (double d) : _d { d } {}
    void doSomething () const { cout << _d << endl; return; }
    void changeSomething ()   { ++_d; return; }
  private:
    double _d;
};

vector<T> v;
// ...
for (const auto iter = v.cbegin(); iter != v.cend(); ++iter) {
    iter->doSomething();
}

还要注意,在c++ 11表示法中,默认是复制元素。使用引用来避免这种情况,和/或允许修改原始元素:

vector<T> v;
// ...
for (auto t : v) {
    t.changeSomething(); // changes local t, but not element of v
    t.doSomething();
}
for (auto& t : v) {      // reference avoids copying element
    t.changeSomething(); // changes element of v
    t.doSomething();
}
for (const auto& t : v) { // reference avoids copying element
    t.doSomething();      // element can not be changed
}