使用“for”循环遍历 C++ 向量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12702561/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Iterate through a C++ Vector using a 'for' loop
提问by Flynn
I am new to the C++ language. I have been starting to use vectors, and have noticed that in all of the code I see to iterate though a vector via indices, the first parameter of the for
loop is always something based on the vector. In Java I might do something like this with an ArrayList:
我是 C++ 语言的新手。我已经开始使用向量,并注意到在我看到的所有通过索引迭代向量的代码中,循环的第一个参数for
总是基于向量的东西。在 Java 中,我可能会用 ArrayList 做这样的事情:
for(int i=0; i < vector.size(); i++){
vector[i].doSomething();
}
Is there a reason I don't see this in C++? Is it bad practice?
有什么原因我在 C++ 中看不到这个吗?这是不好的做法吗?
采纳答案by Alok Save
Is there any reason I don't see this in C++? Is it bad practice?
有什么理由我在 C++ 中看不到这个吗?这是不好的做法吗?
No. It is not a bad practice, but the following approach renders your code certain flexibility.
不。这不是一个坏习惯,但以下方法使您的代码具有一定的灵活性。
Usually, pre-C++11 the code for iterating over container elements uses iterators, something like:
通常,在 C++11 之前,迭代容器元素的代码使用迭代器,例如:
std::vector<int>::iterator it = vector.begin();
This is because it makes the code more flexible.
这是因为它使代码更加灵活。
All standard library containers support and provide iterators. If at a later point of development you need to switch to another container, then this code does not need to be changed.
所有标准库容器都支持并提供迭代器。如果在以后的开发阶段您需要切换到另一个容器,则不需要更改此代码。
Note:Writing code which works with every possible standard library container is not as easy as it might seem to be.
注意:编写适用于所有可能的标准库容器的代码并不像看起来那么容易。
回答by iammilind
The reason why you don't see such practice is quite subjective and cannot have a definite answer, because I have seen many of the code which uses your mentioned way rather than iterator
style code.
您看不到这种做法的原因是非常主观的,无法给出明确的答案,因为我已经看到许多使用您提到的方式而不是iterator
样式代码的代码。
Following can be reasons of people not considering vector.size()
way of looping:
以下可能是人们不考虑vector.size()
循环方式的原因:
- Being paranoid about calling
size()
every time in the loop condition. However either it's a non-issue or it can be trivially fixed - Preferring
std::for_each()
over thefor
loop itself - Later changing the container from
std::vector
to other one (e.g.map
,list
) will also demand the change of the looping mechanism, because not every container supportsize()
style of looping
- 对
size()
每次在循环条件中调用都感到偏执。但是,这要么不是问题,要么可以轻松解决 - 宁愿
std::for_each()
在for
循环本身 - 以后将容器从
std::vector
另一个(例如map
,list
)更改也将要求更改循环机制,因为并非每个容器都支持size()
循环样式
C++11 provides a good facility to move through the containers. That is called "range based for loop" (or "enhanced for loop" in Java).
C++11 提供了一个很好的工具来移动容器。这称为“基于范围的 for 循环”(或 Java 中的“增强型 for 循环”)。
With little code you can traverse through the full (mandatory!) std::vector
:
只需少量代码,您就可以遍历完整的(强制性!)std::vector
:
vector<int> vi;
...
for(int i : vi)
cout << "i = " << i << endl;
回答by JohnB
The cleanest way of iterating through a vector is via iterators:
迭代向量的最干净的方法是通过迭代器:
for (auto it = begin (vector); it != end (vector); ++it) {
it->doSomething ();
}
or (equivalent to the above)
或(相当于上述)
for (auto & element : vector) {
element.doSomething ();
}
Prior to C++0x, you have to replace auto by the iterator type and use member functions instead of global functions begin and end.
在 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?
这大概就是你所看到的。与您提到的方法相比,优点是您不会严重依赖vector
. 如果您更改vector
为不同的“集合类型”类,您的代码可能仍然有效。但是,您也可以在 Java 中执行类似的操作。概念上没有太大区别;然而,C++ 使用模板来实现这一点(与 Java 中的泛型相比);因此,该方法适用于定义了begin
和end
函数的所有类型,甚至适用于静态数组等非类类型。请参阅此处:基于范围的 for 普通数组如何工作?
回答by DiGMi
The right way to do that is:
正确的做法是:
for(std::vector<T>::iterator it = v.begin(); it != v.end(); ++it) {
it->doSomething();
}
Where T is the type of the class inside the vector. For example if the class was CActivity, just write CActivity instead of T.
其中 T 是向量内的类的类型。例如,如果类是 CActivity,只需编写 CActivity 而不是 T。
This type of method will work on every STL (Not only vectors, which is a bit better).
这种类型的方法适用于每个 STL(不仅是向量,这更好一点)。
If you still want to use indexes, the way is:
如果还想使用索引,方法是:
for(std::vector<T>::size_type i = 0; i != v.size(); i++) {
v[i].doSomething();
}
回答by Eddie Parker
There's a couple of strong reasons to use iterators, some of which are mentioned here:
使用迭代器有几个充分的理由,这里提到了其中的一些:
Switching containers later doesn't invalidate your code.
稍后切换容器不会使您的代码无效。
i.e., if you go from a std::vector to a std::list, or std::set, you can't use numerical indices to get at your contained value. Using an iterator is still valid.
即,如果您从 std::vector 转到 std::list 或 std::set,则无法使用数字索引来获取包含的值。使用迭代器仍然有效。
Runtime catching of invalid iteration
无效迭代的运行时捕获
If you modify your container in the middle of your loop, the next time you use your iterator it will throw an invalid iterator exception.
如果在循环中间修改容器,下次使用迭代器时,它将抛出无效的迭代器异常。
回答by Diomidis Spinellis
I was surprised nobody mentioned that iterating through an array with an integer index makes it easy for you to write faulty code by subscripting an array with the wrong index. For example, if you have nested loops using i
and j
as indices, you might incorrectly subscript an array with j
rather than i
and thus introduce a fault into the program.
我很惊讶没有人提到迭代具有整数索引的数组使您很容易通过为具有错误索引的数组添加下标来编写错误代码。例如,如果嵌套循环使用i
andj
作为索引,则可能会错误地使用j
而不是数组下标i
,从而将错误引入程序。
In contrast, the other forms listed here, namely the range based for
loop, and iterators, are a lot less error prone. The language's semantics and the compiler's type checking mechanism will prevent you from accidentally accessing an array using the wrong index.
相比之下,这里列出的其他形式,即基于范围的for
循环和迭代器,更不容易出错。语言的语义和编译器的类型检查机制将防止您使用错误的索引意外访问数组。
回答by ForEveR
With STL, programmers use iterators
for traversing through containers, since iterator is an abstract concept, implemented in all standard containers. For example, std::list
has no operator []
at all.
使用 STL,程序员iterators
用于遍历容器,因为迭代器是一个抽象概念,在所有标准容器中都实现。例如,std::list
根本没有operator []
。
回答by Hrishikesh
Using the auto operator really makes it easy to use as one does not have to worry about the data type and the size of the vector or any other data structure
使用 auto 运算符真的很容易使用,因为人们不必担心数据类型和向量或任何其他数据结构的大小
Iterating vector using auto and for loop
使用 auto 和 for 循环迭代向量
vector<int> vec = {1,2,3,4,5}
for(auto itr : vec)
cout << itr << " ";
Output:
输出:
1 2 3 4 5
You can also use this method to iterate sets and list. Using autoautomatically detects the data type used in the template and lets you use it.
So, even if we had a vector
of string
or char
the same syntax will work just fine
您还可以使用此方法迭代集合和列表。使用auto 会自动检测模板中使用的数据类型并让您使用它。所以,即使我们有vector
ofstring
或char
相同的语法也能正常工作
回答by Nikhil Rai
The correct way of iterating the loop and printing its values are as follows:
迭代循环并打印其值的正确方法如下:
#include<vector>
//declare the vector of type int
vector<int> v;
//insert the 5 element in the vector
for ( unsigned int i = 0; i < 5; i++){
v.push_back(i);
}
//print those element
for (auto it = 0; it < v.end(); i++){
std::cout << *it << std::endl;
}
回答by Akram Mohammed
Here is a simpler way to iterate and print values in vector.
这是在向量中迭代和打印值的更简单方法。
for(int x: A) // for integer x in vector A
cout<< x <<" ";