加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 将列表初始化对插入std :: map

发布时间:2020-12-16 07:22:55 所属栏目:百科 来源:网络整理
导读:我正在尝试将仅移动类型插入到地图中.我有以下代码: #include mapclass Moveable{public: Moveable() = default; Moveable(const Moveable) = delete; Moveable(Moveable) = default; Moveable operator=(const Moveable) = delete; Moveable operator=(Mov
我正在尝试将仅移动类型插入到地图中.我有以下代码:

#include <map>

class Moveable
{
public:
    Moveable() = default;
    Moveable(const Moveable&) = delete;
    Moveable(Moveable&&) = default;
    Moveable& operator=(const Moveable&) = delete;
    Moveable& operator=(Moveable&&) = default;
};

int main() {
    std::map<int,Moveable> my_map;
    Moveable my_moveable_1,my_moveable_2,my_moveable_3;
    my_map.insert(std::pair<int,Moveable>{1,std::move(my_moveable_1)}); // (1)
    my_map.insert(std::make_pair(2,std::move(my_moveable_2)));          // (2)
    my_map.insert({3,std::move(my_moveable_3)});                        // (3)

    return 0;
}

会发生什么是使用VisualC第1,2和3行编译.在clang和gcc中,只有1和2编译,第3行给出错误(使用已删除的复制构造函数).

问题:哪个编译器是正确的,为什么?

在这里试试:rextester

解决方法

std :: map :: insert具有(以及其他)以下重载:

// 1.
std::pair<iterator,bool> insert( const value_type& value );

// 2. (since C++11)
template< class P >
std::pair<iterator,bool> insert( P&& value );

// 3. (since C++17)
std::pair<iterator,bool> insert( value_type&& value );

第一个过载显然不能与仅移动类型一起使用.但是第二次重载虽然在C 11中可用,但在这里不适用于括号,因为大括号不会出现模板参数推断(至少在C 11中,不确定以后的标准).

第一次和第二次调用都是在C 11或更高版本中插入工作,因为编译器知道类型,但第三次失败.

C 17增加了另一个与大括号和仅移动类型一起使用的重载.现在,为什么它适用于某些编译器而不是其他编译器,这很可能是由于C 17支持或编译器标志的差异造成的.

更新:只是让它显而易见:使用大括号我的意思是仅使用大括号(聚合初始化或隐式构造函数调用),即插入({k,v}),而不是插入(对< K,V> {k,v} ).在后一种情况下,类型是已知的,即使在C 11中也可以选择模板化过载.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读