3

If I have a type like this

std::vector<int> const value = ...

Which one is a better solution?

style 1 :

for(auto v : value){
  //do something
}

style 2 :

for(auto &&v : value){
  //do something
}

style 3 :

for(auto const v : value){
  //do something
}

All of them keep the constness of the type.

Style 2 is the most generic solution.

According to what I know, for primitive type like int, double etc, pass by value is prefer over pass by const reference, so I think style 1 and style 3 is better than style 2 if we know the type of vector is primitive type. Please forgive me if this question sound stupid.

StereoMatching
  • 4,971
  • 6
  • 38
  • 70

1 Answers1

8

It really depends on your needs and what you're iterating over.

Styles 1 and 3 make a copy of the element. This means you can't change the original container. For small types it may be beneficial in terms of performance (benchmark yourself on your target architecture), but usually is just a bad default.

You then have to decide whether you're one of the const by default folks. If yes, take style 3.


Style 2 is indeed most generic, but not necessarily in the good way. Unless you want to further move from the element, there's little point to taking a non-const reference to a sequence generated on the spot, i.e.:

for(auto&& x : std::vector<int>{1,2,3})
{
    // x = 42; ???
}

If you look at C++ Core Guidelines here and here, you'll see no examples with auto&& and they suggest taking const& by default unless you're going to modify the variable. That's what I'd stick to.

krzaq
  • 16,240
  • 4
  • 46
  • 61