Is it bug or standart permits it?
#include <iostream>
#include <map>
#include <unordered_map>
int main() {
std::unordered_map<int,int> mm {{44,44}, {33.3, 54}, {222.2,222.2}};
for(auto& [f,s] :mm) {
std::cout<<f<<" - "<<s<<std::endl;
}
std::map<int,int> m {{44,44}, {33.3, 54}, {222.2,222.2}};
for(auto& [f,s] :m) {
std::cout<<f<<" - "<<s<<std::endl;
}
}
Test it on wandbox.org with clang10 and gcc10. There is not such problem with std::set
and std::unordered_set
.
The element type of std::map
and std::unordered_map
is std::pair
. The problem is that std::pair
has a templated constructor,
template< class U1, class U2 > constexpr pair( U1&& x, U2&& y );
Initializes
first
withstd::forward<U1>(x)
andsecond
withstd::forward<U2>(y)
.
E.g. given {33.3, 54}
, U1
is deduced as double
and U2
is deduced as int
, note that this is an exact match and no conversions are required for this constructor to be used to construct the std::pair
, then no narrowing conversion happens either.
On the other hand, for std::set
, given std::set<int> s {33.3};
, the constructor of std::set
taking std::initializer_list<int>
will be used, and the std::initializer_list<int>
is initialized from {33.3}
, narrow conversion happens.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With