Using C++14 (should also affect C++11) I'm confused about auto
in a range-based for-loop through an std::unordered_map
, in contrast of using the exact type like std::pair<int, int>
in the code below.
More specifically I have some (related) questions concerning the example:
std::pair<int, int> &
not allowed but auto &
in loop 1 is?auto
differ from the exact type (like std::pair<int, int>
in loop 0)?Question 3: (loop 3) Why are this the same pointers for all map entries?
Question 4 (continues 0 and 1): I know that the range-based for-loop uses an iterator. But why can I iterate through an std::unordered_map
with reference to non-const using auto
(loop 1), but not when using std::pair
(loop 0)?
#include<iostream>
#include <unordered_map>
#include <utility>
int main()
{
std::unordered_map<int, int> map;
map[3] = 333;
map[2] = 222;
map[1] = 111;
// loop 0
// QUESTION 0: Why is `std::pair<int, int> &` not allowed but `auto &` in loop 1 is?
// for(std::pair<int, int> & pair : map)
// pair.second++;
// loop 1
for(auto & pair : map)
// QUESTION 1: Why/How/When does `auto` differ from the exact type (like `std::pair<int, int>` in loop 0)?
pair.second++;
// loop 2
for(auto const & pair : map)
// QUESTION 2: Why are this different pointers than in loop 3?
std::cout << pair.first << " (" << &pair.first << ") : " << pair.second << " (" << &pair.second << ")" << std::endl;
// loop 3
for(std::pair<int, int> const & pair : map)
// QUESTION 3: Why are this the same pointers for all map entries?
std::cout << pair.first << " (" << &pair.first << ") : " << pair.second << " (" << &pair.second << ")" << std::endl;
return 0;
}
You can run the code here: https://www.onlinegdb.com/rkBkKDatf
The value type of a std::unordered_map
is std::pair<const Key, T>
. See the documentation at cppreference.com.
Hence, you cannot use std::pair<int, int>&
as the type to iterate over the contents of such an object.
That explains why
for(std::pair<int, int> & pair : map) { ... }
does not work.
The following works
for(auto const & pair : map)
since the type is deduced for you by the compiler.
The following works
for(std::pair<int, int> const & pair : map)
since pair
is bound to a temporary object of type std::pair<int, int>
constructed from a std::pair<const int, int>
.