[c++] Iterate through a C++ Vector using a 'for' loop

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:

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?

This question is related to c++ coding-style for-loop iterator

The answer is


A correct way of iterating over the vector and printing its values is as follows:

#include<vector>

// declare the vector of type int
vector<int> v;

// insert elements in the vector
for (unsigned int i = 0; i < 5; ++i){
    v.push_back(i);
}

// print those elements
for (auto it = v.begin(); it != v.end(); ++it){
    std::cout << *it << std::endl;
}

But at least in the present case it is nicer to use a range-based for loop:
for (auto x: v) std::cout << x << "\n";
(You may also add & after auto to make x a reference to the elements rather than a copy of them. It is then very similar to the above iterator-based approach, but easier to read and write.)


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.

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.


Here is a simpler way to iterate and print values in vector.

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

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.

This type of method will work on every STL (Not only vectors, which is a bit better).

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();
}

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.

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?


If you use

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

Do not forget, when you use auto in the for loop, to use also get, like this:

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

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

Iterating vector using auto and for loop

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 auto automatically 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


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.

Following can be reasons of people not considering vector.size() way of looping:

  1. Being paranoid about calling size() every time in the loop condition. However either it's a non-issue or it can be trivially fixed
  2. Preferring std::for_each() over the for loop itself
  3. 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 support size() style of looping

C++11 provides a good facility to move through the containers. That is called "range based for loop" (or "enhanced for loop" in Java).

With little code you can traverse through the full (mandatory!) std::vector:

vector<int> vi;
...
for(int i : vi) 
  cout << "i = " << i << endl;

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

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.


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.

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.


Examples related to c++

Method Call Chaining; returning a pointer vs a reference? How can I tell if an algorithm is efficient? Difference between opening a file in binary vs text How can compare-and-swap be used for a wait-free mutual exclusion for any shared data structure? Install Qt on Ubuntu #include errors detected in vscode Cannot open include file: 'stdio.h' - Visual Studio Community 2017 - C++ Error How to fix the error "Windows SDK version 8.1" was not found? Visual Studio 2017 errors on standard headers How do I check if a Key is pressed on C++

Examples related to coding-style

Method Call Chaining; returning a pointer vs a reference? 80-characters / right margin line in Sublime Text 3 Cannot find reference 'xxx' in __init__.py - Python / Pycharm How to stick <footer> element at the bottom of the page (HTML5 and CSS3)? Simple way to create matrix of random numbers Is calling destructor manually always a sign of bad design? Count all values in a matrix greater than a value Iterate through a C++ Vector using a 'for' loop Which comment style should I use in batch files? Dictionaries and default values

Examples related to for-loop

List append() in for loop Prime numbers between 1 to 100 in C Programming Language Get current index from foreach loop how to loop through each row of dataFrame in pyspark TypeScript for ... of with index / key? Is there a way in Pandas to use previous row value in dataframe.apply when previous value is also calculated in the apply? Python for and if on one line R for loop skip to next iteration ifelse How to append rows in a pandas dataframe in a for loop? What is the difference between ( for... in ) and ( for... of ) statements?

Examples related to iterator

Iterating over Typescript Map Update row values where certain condition is met in pandas How to iterate (keys, values) in JavaScript? How to convert an iterator to a stream? How to iterate through a list of objects in C++ How to avoid "ConcurrentModificationException" while removing elements from `ArrayList` while iterating it? How to read one single line of csv data in Python? 'numpy.float64' object is not iterable Python list iterator behavior and next(iterator) python JSON only get keys in first level