1

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.

2
  • 1
    is your question which is better or why doesn't your code work? please stick to one question per post Commented May 19, 2021 at 7:29
  • "not much better than the previous examples" I.e. it is some improvement, but still not as good as it can be Commented May 19, 2021 at 7:58

4 Answers 4

3

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.

Sign up to request clarification or add additional context in comments.

Comments

0

In

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

i is an iterator, you have to deference it to retrieve the value to be nearly equivalent to second snippet.

Comments

0

Regular for loop uses an explicit loop variable, in your examples an iterator i or iter (many times it is just an integer). To access elements in a vector for example, you need to use the loop variable to extract the elements from the vector.

Range-based for loops automatically gives you the elements inside the container you loop over, so there is no need to extract the elements inside the loop, you can immediately use k/elem.

About the comment you mention: that specific range-based style with no references is usually bad for performance (if the copy is unnecessary).

Comments

0

So, what is the difference between these two statement:

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

The first one will iterate through every item in the collection; i is a copy of the item.

The second one gives you more control over the range; i is an iterator, dereference to access item.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.