我不熟悉c++语言。我已经开始使用向量,并注意到在我看到的所有通过索引遍历向量的代码中,for循环的第一个参数总是基于向量的值。在Java中,我可以对数组列表做这样的事情:
for(int i=0; i < vector.size(); i++){
vector[i].doSomething();
}
我在c++中看不到这个的原因是什么呢?这是不好的做法吗?
我不熟悉c++语言。我已经开始使用向量,并注意到在我看到的所有通过索引遍历向量的代码中,for循环的第一个参数总是基于向量的值。在Java中,我可以对数组列表做这样的事情:
for(int i=0; i < vector.size(); i++){
vector[i].doSomething();
}
我在c++中看不到这个的原因是什么呢?这是不好的做法吗?
当前回答
使用迭代器有几个强有力的理由,这里提到了其中一些:
稍后切换容器不会使代码失效。
例如,如果从std::vector转换为std::list或std::set,则不能使用数值索引来获取包含的值。使用迭代器仍然有效。
无效迭代的运行时捕获
如果在循环中间修改容器,下次使用迭代器时,它将抛出一个无效的迭代器异常。
其他回答
int main()
{
int n;
int input;
vector<int> p1;
vector<int> ::iterator it;
cout << "Enter the number of elements you want to insert" << endl;
cin >> n;
for (int i = 0;i < n;i++)
{
cin >> input;
p1.push_back(input);
}
for(it=p1.begin();it!=p1.end();it++)
{
cout << *it << endl;
}
//Iterating in vector through iterator it
return 0;
}
迭代器的常规形式
在STL中,程序员使用迭代器遍历容器,因为迭代器是一个抽象概念,在所有标准容器中实现。例如,std::list根本没有操作符[]。
使用迭代器有几个强有力的理由,这里提到了其中一些:
稍后切换容器不会使代码失效。
例如,如果从std::vector转换为std::list或std::set,则不能使用数值索引来获取包含的值。使用迭代器仍然有效。
无效迭代的运行时捕获
如果在循环中间修改容器,下次使用迭代器时,它将抛出一个无效的迭代器异常。
如果你使用
std::vector<std::reference_wrapper<std::string>> names{ };
不要忘记,当你在for循环中使用auto时,也要使用get,就像这样:
for (auto element in : names)
{
element.get()//do something
}
不要忘记具有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
}