试图将unique_ptr放入映射时发生编译错误

Compile error trying to put a unique_ptr into a map

本文关键字:映射 错误 编译 unique ptr      更新时间:2023-10-16

我有一个加载方法来构建我的unique_ptr(稍后会有多个),还有一个方法将这些unique_pr添加到我的无序映射中。但代码没有编译,我想这与作用域有关。。。

这是代码:

#include <unordered_map>
#include <memory>
class MyClass
{
    public:
        std::string Name;
};
using Map = std::unordered_map<std::string,std::unique_ptr<MyClass>>;

class MyContainer
{
    private:
        Map myMap;
        void AddItem(std::unique_ptr<MyClass> item)
        {
            myMap.emplace("test", item);
        }
    public:
        void LoadItems()
        {
            //Read a file ... do something before etc..
            std::unique_ptr<MyClass> someItem(new MyClass);
            someItem->Name = "FooBar";
            AddItem(someItem);
        }
};

这是g++错误消息之一:

错误:使用已删除的函数'std::unique_ptr&lt_Tp,_Dp>::unique_ptr(const std::unique_pr<_Tp,_Dp>&)[with_Tp=MyClass;_Dp=std::default_delete]'

实现这一目标的最佳方法是什么?我尝试更改AddItem方法的签名,如下所示:

void AddItem(std::unique_ptr<MyClass>& item) //takes a reference now...

这导致了一个真正神秘的错误消息:

在'constexpr std::pair&lt_T1,_T2>::对(_U1&&,常量_T2&)[带_U1=常量字符(&)[5];=空洞_T1=常量std::basic_string_T2=std::unique_ptr]':e:\devtools\winbuilds\include\c++\4.8.3\bits\hashtable_policy.h:177:55:需要从'std::__detail::_。。。

我建议在这里快速尝试这段代码,以查看错误消息:http://cpp.sh/

不能复制unique_ptr,因为这样它就不是唯一的。你必须移动它——AddItem(std::move(someItem));myMap.emplace("test", std::move(item));

您正试图复制unique_ptr,这是不允许的(正如gcc在错误中所说,该构造函数已被删除)。相反,您可以尝试使用std::move

#include <unordered_map>
#include <memory>
#include <utility>
class MyClass
{
    public:
         std::string Name;
};
using Map = std::unordered_map<std::string,std::unique_ptr<MyClass>>;

class MyContainer
{
    private:
        Map myMap;
        void AddItem(std::unique_ptr<MyClass> item)
        {
            myMap.emplace("test", std::move(item));
        }
    public:
        void LoadItems()
        {
            //Read a file ... do something before etc..
            std::unique_ptr<MyClass> someItem(new MyClass);
            someItem->Name = "FooBar";
            AddItem(std::move(someItem));
        }
};

请注意,之后不要使用移动的对象。

您可以考虑使用shared_ptr