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

c – std :: map <> :: insert使用非可复制对象和均匀初始

发布时间:2020-12-16 03:47:39 所属栏目:百科 来源:网络整理
导读:看看下面的代码: #include utility#include map// non-copyable but movablestruct non_copyable { non_copyable() = default; non_copyable(non_copyable) = default; non_copyable operator=(non_copyable) = default; // you shall not copy non_copyabl
看看下面的代码:
#include <utility>
#include <map>

// non-copyable but movable
struct non_copyable {
    non_copyable() = default;

    non_copyable(non_copyable&&) = default;
    non_copyable& operator=(non_copyable&&) = default;

    // you shall not copy
    non_copyable(const non_copyable&) = delete;
    non_copyable& operator=(const non_copyable&) = delete;
};

int main() {
    std::map<int,non_copyable> map;
    //map.insert({ 1,non_copyable() });  < FAILS
    map.insert(std::make_pair(1,non_copyable()));
    // ^ same and works
}

取消注释g 4.7上的标记行时,编译此代码段将失败.所产生的错误表示non_copyable不能被复制,但我预计将被移动.

为什么插入使用均匀初始化构造的std :: pair失败但不是使用std :: make_pair构造的?两者都不应该产生可以成功地移动到地图中的值吗?

解决方法

[这是一个完整的重写.我以前的答复与这个问题无关.]

该地图有两个相关的插入重载:

> insert(const value_type& value),和
>< template typename P>插入(P&& value).

当您使用简单的list-initializer map.insert({1,non_copyable()});所有可能的重载被考虑.但是只有第一个(占用了const value_type&),因为另一个没有意义(没有办法神奇地猜测你打算创建一个对).当然,第一个重载不起作用,因为你的元素不可复制.

您可以通过使用make_pair显式创建对象,如您已经描述的那样,或通过明确命名值类型来使第二个重载工作:

typedef std::map<int,non_copyable> map_type;

map_type m;
m.insert(map_type::value_type({1,non_copyable()}));

现在,列表初始化器知道要查找map_type :: value_type构造函数,找到相关的可移动的构造函数,结果是一个rvalue对,它绑定到插入函数的P& -overload.

(另一个选择是使用片段式构造和forward_as_tuple来使用emplace(),尽管这样会更详细一些.)

我认为这里的道德是列表初始化器寻找可行的重载 – 但是他们必须知道要寻找的内容!

(编辑:李大同)

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

    推荐文章
      热点阅读