I am trying to see the deduced type in structured binding for an unordered_map by using auto
, auto &
and auto &&
.
#include <string>
#include <iostream>
#include <unordered_map>
#include <type_traits>
int main() {
std::unordered_map<std::string, std::string> m{{"a","a1"}, {"b","b1"}};
for(auto && [k,v]:m)
{
std::cout << std::is_same<decltype(k), std::string const >::value << '\n';
std::cout << std::is_same<decltype(v), std::string >::value << '\n';
}
}
No matter i use for(auto [k,v]:m)
or for(auto & [k,v]:m)
or for(auto && [k,v]:m)
, the output is always
1
1
My questions are:
why decltype(k)
and decltype(v)
is not reference type in the case of for(auto & [k,v]:m)
or for(auto && [k,v]:m)
?
why decltype(k)
is of type const
in the case of for(auto [k,v]:m)
?
Question 1) Like specified here
1) If the argument is an unparenthesized id-expression naming a structured binding, then decltype yields the referenced type (described in the specification of the structured binding declaration).
and here:
Case 2: binding a tuple-like type [...] The referenced type for the i-th identifier is
std::tuple_element<i, E>::type
.
A std::pair
(see answer to question 2) is effectively a tuple of 2. Thus it is 'tuple-like'.
Thus in this case the base type of Key and T are always returned (yielded).
Question 2)
Internally the unordered_map
is allocated as a std::pair<const Key, T>
. Hence, the k is const
.