The auto
keyword by itself represents a value type, similar to int
or char
. It can be modified with the const
keyword and the &
symbol to represent a const type or a reference type, respectively. These modifiers can be combined.
In this example, s
is a value type (its type will be inferred as std::string
), so each iteration of the for
loop copies a string from the vector into s
.
std::vector<std::string> strings = { "stuff", "things", "misc" };
for(auto s : strings) {
std::cout << s << std::endl;
}
If the body of the loop modifies s
(such as by calling s.append(" and stuff")
), only this copy will be modified, not the original member of strings
.
On the other hand, if s
is declared with auto&
it will be a reference type (inferred to be std::string&
), so on each iteration of the loop it will be assigned a reference to a string in the vector:
for(auto& s : strings) {
std::cout << s << std::endl;
}
In the body of this loop, modifications to s
will directly affect the element of strings
that it references.
Finally, if s
is declared const auto&
, it will be a const reference type, meaning that on each iteration of the loop it will be assigned a const reference to a string in the vector:
for(const auto& s : strings) {
std::cout << s << std::endl;
}
Within the body of this loop, s
cannot be modified (i.e. no non-const methods can be called on it).
When using auto
with range-based for
loops, it is generally good practice to use const auto&
if the loop body will not modify the structure being looped over, since this avoids unnecessary copies.