Auto vs. specific type when iterating over a vector?

The book I'm reading offers this example when iterating over vector

 for (auto &e: v) { cout << e << endl; } 

Suppose v is declared as vector<int> v , in other words, we know that the type of elements inside this collection is int .

Does auto use any way better or preferable?

 for (int &e: v) { cout << e << endl; } 

Why?

+7
source share
2 answers

Yes. auto is preferred. Because if you change the declaration of v to:

 std::vector<int> v; //before 

:

 std::vector<float> v; //after 

If you use int & in for , you also need to change this. But with auto no need to change!

In my opinion, working with auto more or less like programming on an interface . Therefore, if you perform the += operation in a loop, and you do not need the type of the loop variable e , as long as the type supports the += operation, then auto is the solution:

 for(auto & e : v) { e += 2; } 

In this example, you don't care that type e supports += with int on the right side. It will work even for custom types that defined operator+=(int) or operator+=(T) , where T is a type that supports implicit conversion from int . It is as if you were programming an interface:

 std::vector<Animal*> animals; animals.push_back(new Dog()); animals.push_back(new Cat()); animals.push_back(new Horse()); for(size_t i = 0 ; i < animals.size(); ++i) { animals[i]->eat(food); //program to interface } 

Of course you would like to write this loop as:

 for(Animal * animal : animals) { animal->eat(food); //still program to interface } 

Or just this:

 for(auto animal : animals) { animal->eat(food); //still program to interface } 

He is still programming for the interface .

But at the same time, it’s worth noting the comment in the @David comment.

+6
source

In the first example, you have less dependence on the elements of the vector.

Suppose in a month you need your vector to store more integers, so you have to use std::vector<int64_t> or some other wider type. Now all the code that iterates over this vector is invalid. You will need to change each of them:

 for (int &e: v) {} 

For a:

 for (int64_t &e: v) {} 

That's why it's better to just let auto infer an internal type. This way you can change the type stored in your vector to another compatible one, and all your code will work.

+1
source

All Articles