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
firstwithstd::forward<U1>(x)andsecondwithstd::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