const auto& for loop

Hello,

in which cases is it necessary to use a for loop on the form
1
2
3
for(const auto &i : vec){
   std::cout << i << std::endl;
}


rather than on the form

1
2
3
for(auto i : vec){
   std::cout << i << std::endl;
} 


I know the last one results in a copy of each element of vec (an std::vector), which may be expensive. My question is: in which situations is the first form necessary?

As an example, in this case:

1
2
3
4
5
6
ostream& operator<<(ostream& out,const CourseCatalog& c) {
    
    for (const auto &p : c.courses) {
        out << p.first << ":" << p.second << '\n';
    }
    return out; 

do I need to have const auto& p here?

here CourseCatalog is a class, which has a member map (non const.) which is defined like this:

 
    map<string,string> courses;

Last edited on
I know the last one results in a copy of each element of vec (an std::vector), which may be expensive. My question is: in which situations is the first form necessary?


It's never necessary, but it could be advantageous if the elements of the container are large and hence relatively expensive to copy. If they are just ints then it would be disadvantageous.


do I need to have const auto& p here?


No. But if a CourseCatalogue is large then it eventually becomes advantageous to avoid making a copy (hence the &p rather than p) and once you have introduced a reference then you can change a value unwittingly, so you may choose to enforce the const.


Where the sweet point between simply copying a value and using a const reference lies I don't know. My personal take is that it's about at the point where I stop using the actual types of variables and start using "auto".

I personally dislike excessive use of const, especially when your loop is only two or three lines long so that it's perfectly obvious whether a variable is changed or not, and some of the syntax of c++ is verbose enough as it is. However, that's an entirely personal view and I'm well aware that I'm in a minority about it in this forum.
Last edited on
If you want to change the values in the container, reference is necessary.

Otherwise, it's your choice. Nobody will shoot you if you make a copy that you didn't need to. It's not necessary. Extra copies are a waste of time, and not everything can be copied, but it's not necessary.

Code is also for communicating with humans who read it. If anyone else ever reads your code they will read "const auto& i" as meaning "I don't need to change the container and I just want to read values from it", and they will read "auto i" as meaning "I need a copy because I don't want to change the container but I do still need to alter the value". If you then don't do what you said you were going to do, they will wonder if you made a mistake or if you're just not very good at C++ programming.

Petr Zemek goes into detail on all your options: https://blog.petrzemek.net/2016/08/17/auto-type-deduction-in-range-based-for-loops/
Last edited on
Topic archived. No new replies allowed.