Here’s a simple for-loop:
std::unordered_map<int, unsigned> map;
for (std::pair<int, unsigned> const &kv : map) {
// ...
}
GCC and Clang give a -Wrange-loop-construct
for this code, saying I’m making a copy.
GCC’s warning says:
src/main.cpp:26:37: warning: loop variable ‘kv’ of type ‘const std::pair<int, unsigned int>&’ binds to a temporary constructed from type ‘std::pair<const int, unsigned int>’ [-Wrange-loop-construct]
26 | for (pair<int, unsigned> const &kv : count) {
| ^~
src/main.cpp:26:37: note: use non-reference type ‘const std::pair<int, unsigned int>’ to make the copy explicit or ‘const std::pair<const int, unsigned int>&’ to prevent copying
Why is this?
I would have guessed this is because internally, we don’t necessarily store key-value pair
s, so the iterator constructs a std::pair<K, V>
by copying the K
and V
.
0
The map stores std::pair<const int, unsigned>
objects, with the first type being const.
I would have guessed this is because internally, we don’t necessarily store key-value
pair
s, so the iterator constructs apair<K, V>
by copying theK
andV
…
Yes, thats it. std::unordered_map<K,V>::value_type
, the type of the elements in the container, is std::pair<const K,V>
. See here.
You need to read the message more carefully. The important parts are:
...blablala... loop variable ‘kv’ of type ‘const std::pair<int, unsigned int>&’
...binds... from type ‘std::pair<const int, unsigned int>’
The keys in the map are const
. You can use
for (pair<const int, unsigned> const &kv : map) {
or simply
for (const auto& kv : map) {
to avoid the warning. The conversion to the pair with non-const key requires to create a temporary pair that you do not need when you chose the right type.