Search code examples
c++for-loopc++11auto

C++11 Range-based for-loop efficiency "const auto &i" versus "auto i"


In C++11, I can iterate over some container like so:

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

But I know that this needlessly - needlessly, since I only need to print the values of vec - makes a copy of (EDIT: each element of) vec, so instead I could do:

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

But I want to make sure that the values of vec are never modified and abide by const-correctness, so I can do:

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

So my question is: If I only need to look at the values of some container, wouldn't the very last loop (const auto &i) always be preferred due to the increased effieciency of not having an extra copy of (EDIT: each element of) vec?

I have a program that I'm developing in which I'm considering making this change throughout, since efficiency is critical in it (the reason I'm using C++ in the fist place).


Solution

  • Yes. The same reason if you only ever read an argument you make the parameter const&.

    T        // I'm copying this
    T&       // I'm modifying this
    const T& // I'm reading this
    

    Those are your "defaults". When T is a fundamental type (built-in), though, you generally just revert to const T (no reference) for reading, because a copy is cheaper than aliasing.


    I have a program that I'm developing in which I'm considering making this change throughout, since efficiency is critical in it

    1. Don't make blind sweeping changes. A working program is better than a fast but broken program.
    2. How you iterate through your loops probably won't make much of a difference; you're looping for a reason, aren't you? The body of your loop will much more likely be the culprit.
    3. If efficiency is critical, you want to use a profiler to find which parts of your program are actually slow, rather than guess at parts that might be slow. See #2 for why your guess may be wrong.