简体   繁体   English

std::map、std::unordered_map - 在初始化列表中缩小转换

[英]std::map, std::unordered_map - narrowing conversion in initializer list

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.使用 clang10 和 gcc10 在wandbox.org上对其进行测试。 There is not such problem with std::set and std::unordered_set . std::setstd::unordered_set没有这样的问题。

The element type of std::map and std::unordered_map is std::pair . std::mapstd::unordered_map的元素类型是std::pair The problem is that std::pair has a templated constructor,问题是std::pair有一个模板化的构造函数,

 template< class U1, class U2 > constexpr pair( U1&& x, U2&& y );

Initializes first with std::forward<U1>(x) and second with std::forward<U2>(y) . firststd::forward<U1>(x)初始化, secondstd::forward<U2>(y)初始化。

Eg 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.例如给定{33.3, 54}U1被推导为double并且U2被推导为int ,请注意这是一个完全匹配,并且此构造函数不需要转换来构造std::pair ,那么就没有缩小转换发生。

On the other hand, for std::set , given std::set<int> s {33.3};另一方面,对于std::set ,给定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. ,将使用采用std::initializer_list<int>std::set的构造函数,并且std::initializer_list<int>{33.3}初始化,发生窄转换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM