【问题标题】:Cannot insert std::unique_ptr with custom deleter with std::move无法使用带有 std::move 的自定义删除器插入 std::unique_ptr
【发布时间】:2018-06-28 18:13:37
【问题描述】:

我使用带有自定义删除器的std::unique_ptr 作为std::map 的值,如下所示:

#include <iostream>
#include <memory>
#include <map>

void deleter(int* p){
    std::cout<<"Deleting..."<<std::endl;
    delete p;
}

int main()
{   
    std::map<char, std::unique_ptr<int, void(*)(int*)>> a;
    std::unique_ptr<int, void(*)(int*)> p{new int{3}, deleter}; 
    a['k'] = std::move(p);
}

插入值时,我使用std::move,但是编译不出来。

我做错了什么?

您会看到以下链接的错误。

https://wandbox.org/permlink/fKL4QDkUTDsj4gDc

【问题讨论】:

  • 把最后一行改成a.emplace('k', std::move(p));

标签: c++ unique-ptr stdmap stdmove


【解决方案1】:

a['k'] 如果键不存在,将默认构造映射的值类型。由于您的 unique_ptr 使用自定义删除器,因此它不是默认可构造的。您必须使用map::emplace()map::insert()unique_ptr 添加到地图中。如果您想在这样做之前知道该元素是否存在,您可以使用map::count()map::find()

如果你可以使用 C++17,你可以使用 map::try_emplace() 代替,它只会在 key 不存在时添加对象,省去查找。

【讨论】:

  • 如果你仔细阅读编译器的错误信息,其实是给你指出了默认构造函数问题:“required from ...::operator[](...) ... error: no matching function for call to std::unique_ptr&lt;int, void (*)(int*)&gt;::unique_ptr()"
【解决方案2】:

bug 是在赋值之前默认构造的map entry!

抱歉没有时间来解决这个问题,但通常我会使用 insert 来代替?

【讨论】:

    猜你喜欢
    • 2013-03-30
    • 1970-01-01
    • 2012-04-11
    • 2016-03-31
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    • 2016-03-21
    • 2014-08-27
    相关资源
    最近更新 更多