Search code examples
c++c++11intauto

Auto vs concrete type when iterating over vector?


The book i am reading offers this example when iterating over a 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.

Is using auto in any way better or preferred to?

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

Why?


Solution

  • Yes. auto is preferred. Because if you change the declaration ofv from:

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

    to this:

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

    If you use int & in the for, then you have to change that as well. But with auto, no need to change!

    In my opinion, working with auto is more or less like programming to interface. So if you do an operation += in the loop, and you don't really care about the type of the loop variable e as long as the type supports += operation, then auto is the solution:

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

    In this example, all you care about that the type of e supports += with int on the right hand side. It will work even for user-defined types, which has defined operator+=(int), or operator+=(T) where T is a type which supports implicit conversion from int . It is as if you're programming to 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 simply this:

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

    It is still programming to interface.

    But at the same time, the point in @David's comment is worth noting.