Summary
In this post, I will introduce auto
, const auto
, auto&
, const auto&
, auto&&
, and const auto&&
.
Conclusion
We provide the conclusion first.
- When you want a read-only access (generic or non-generic codes), use
auto const &
, which will give you a reference rather than a copy. - When you want a read-write access in generic codes, use
auto &&
. - When you want a read-write access in non-generic codes, use
auto &
.
Details
auto
Auto will create a copy of each element in the range so use this variant when you want to work with a copy.
Note the following situations.
1. Containers return proxy objects upon dereferencing of their iterators.
std::vector<bool> vec{false, false, false};
for (auto x : vec) {
x = true; // now vec is {true, true, true}
}
const auto
It will provide an immutable copy of each element.
However we should avoid using const auto
because there is no reason we create a copy. Thus, use const auto &
instead.
const auto&
or auto const &
This is the number one choice for iterating over a range when all you want to is read its elements. No copies are made and the compiler can verify that you indeed do not modify the elements.
auto&
Use auto&
when you want to modify elements in the range in non-generic codes. &
means it will make references to the original elements in the range. See special situations (eg, inside templates) in reference.
auto&&
Use auto&&
when you want to modify elements in the range in generic codes. Actually it also works in non-generic codes, but it unnecessarily confuses people. Details are in reference.
const auto&&
There is no reason for choosing this variant over const auto&
.
Reference
See this blog for more details and some special situations.