Search code examples
c++for-loopauto

What is the difference between regular "for" statement and range-based "for" statement in C++


So, what is the difference between these two statement:

for(auto i : VectorName){}


for(auto i = VectorName.begin(); i != VectorName.end(); i++){}

For example, I have this program:

#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
 vector<char> vec = {'H','e','l','l','o','W','o','r','l','d','!'};
 for(auto i = vec.begin(); i != vec.end(); i++) // This loop has error
     {        
     cout << i << endl;
}
 for(auto k : vec) //This loop has no problem
 {
     cout << k << endl;
     }
     return 0;
}

I am confused because in this example in this Microsoft docs:

// cl /EHsc /nologo /W4
#include <deque>
using namespace std;

int main()
{
    deque<double> dqDoubleData(10, 0.1);

    for (auto iter = dqDoubleData.begin(); iter != dqDoubleData.end(); ++iter)
    { /* ... */ }

    // prefer range-for loops with the following information in mind
    // (this applies to any range-for with auto, not just deque)

    for (auto elem : dqDoubleData) // COPIES elements, not much better than the previous examples
    { /* ... */ }

    for (auto& elem : dqDoubleData) // observes and/or modifies elements IN-PLACE
    { /* ... */ }

    for (const auto& elem : dqDoubleData) // observes elements IN-PLACE
    { /* ... */ }
}

They noted that the range for statement is not better than the regular one.


Solution

  • The difference in your case is, that the first version with iterators, well, uses iterators (that's why cout << i << endl; is not working), and the second version (the range-based for loop) gives you either a copy, a reference, or const reference.

    So this:

    for(auto i = vec.begin(); i != vec.end(); i++)
    {
        cout << i << endl; // should be *i
    }
    

    uses iterators (vec.begin() gives you an iterator to the first element).

    Whereas this:

    for(auto i : vec)
    {
        cout << i << endl;
    }
    

    uses copies of elements in your vector.

    While this:

    for(auto& i : vec)
    {
        cout << i << endl;
    }
    

    uses references to your vector elements.