In the code below I use auto (not auto&, const auto, const auto& or auto&&), but k has a reference type.
Why is it captured by reference (as GCC says) and not by value? Looks counterintuitive.
If it's captured by value (as Clang says), why it is captured as const?
What does the standard say about this?
Is there a way to capture it by non-const value (if I want to make further manipulations with k without modifying the map) or I have to make a copy of k inside the loop?
std::map<int, int> map{{3,7},{1,16}};
for (auto [k, v] : map) {
//k *= 3; // error: assignment of read-only reference 'k'
std::printf("k=%i v=%i\n", k, v);
}
GCC produces (https://godbolt.org/z/eq6c6Gxc4):
<source>:9:15: error: assignment of read-only reference 'k'
9 | k *= 3; // error: assignment of read-only reference 'k'
| ~~^~~~
Clang produces (https://godbolt.org/z/K9bcvjqs3):
<source>:9:15: error: cannot assign to variable 'k' with const-qualified type 'std::tuple_element<0, std::pair<const int, int>>::type' (aka 'const int')
9 | k *= 3; // error: assignment of read-only reference 'k'
| ~ ^
<source>:8:20: note: variable 'k' declared const here
8 | for (auto [k, v] : map) {
| ^