首页 > 解决方案 > 将 map 中的 unique_ptrs 推入向量时出错

问题描述

我有一个std::mapofstd::stringstd::unique_ptr<BaseInt>。基本上我想要一个类名作为字符串key和一个唯一指针作为对应的映射value。并访问指针map["Derived1"]等(在下面的代码中解释)。

当我遍历std::map并尝试将每个推value送到 astd::vector时,我看到以下错误

错误 C2280 ' std::unique_ptr<BaseInt,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': 试图引用已删除的函数 CreateInstanceFromList c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\xmemory

我在 Visual Studio 2017 版本 15.9.16 MSVC 14.16.27023

实现代码如下。BaseInt是具有int成员和纯虚拟的 BaseClass replaceInt()DerivedInt1并以不同的值DerivedInt2实现虚函数,并在其构造中因参数而异。int

#include "UserClass.h"
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <memory>
#include <typeinfo>

typedef std::vector<std::unique_ptr<BaseInt>> vec_type;
typedef std::map<std::string, std::unique_ptr<BaseInt>> map_type;

template<typename T> std::unique_ptr<T> createInstance(vec_type& vec) { return std::make_unique<T>(); };
template<typename T, typename U> std::unique_ptr<T> createInstance(vec_type& vec, U u) { return std::make_unique<T>(u); };

void fillVector(map_type& map)
{
    vec_type my_vec;
    for (auto const& it : map )
    {
        std::cout << it.first << std::endl;
        it.second->replaceInt();

        //my_vec.emplace_back(std::move(it.second)); //this line gives error
    }
    // idea is to be able to access the pointer as map["Derived1"]
    std::cout << my_vec.size() << std::endl;
}

int main()
{
    map_type my_map;
    
    my_map.emplace("Derived1", createInstance<DerivedInt1>(my_vec, 7));
    my_map.emplace("Derived2", createInstance<DerivedInt2>(my_vec));

    fillVector(my_map);

    return 0;
}

我的直觉是不知何故我试图调用的复制构造函数,unique_ptr但我实际上并没有看到如何。谢谢。

编辑:

因此,主要问题是const&答案中提到的@ALX23z 的迭代器。以下更改有效:

    for (auto it = map.begin(); it != map.end(); ++it )
    {
        std::cout << it->first << std::endl;
        it->second->replaceInt();

        my_vec.emplace_back(std::move(it->second));
    }

编辑2:

正如多人指出的那样,我犯了一个基本的设计缺陷,即不使用unique_ptras unique。我可以看到您提到的问题,我将研究更改为shared_ptr或修改设计的可能性。感谢所有快速回复。明天我会在这里更新我的更改。

编辑3:

看了主要的项目场景后发现,std::map这里真的只是一个一次性使用的容器,所以我可以把它保存在本地,把所有的所有权都传给std::vector.

再次编辑:

有人对问题投了反对票并标记为关闭它

寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:如何创建最小的、可重现的示例。

我真的希望他们能启发我如何认为这种标记是必要的。我完全提出了重现我所面临的确切问题所必需的简短代码;而不是我实际正在处理的庞大项目代码。我提供了所有必要的信息,甚至凭直觉知道它失败的地方。我添加了多个编辑信息,以便任何读者都能发现它有用。至少,发表评论并解释可以改进的地方。很抱歉的咆哮。

标签: c++c++11c++14

解决方案


该行给出错误,因为您通过 const 迭代器迭代地图。要申请emplace_back,您需要一个非常量参考。

通常,您的方法也有错误。unique_ptr唯一的指针。不能有多个unique_ptr指向同一个对象。所以你不能在地图和矢量之间共享它们。

根据要求使用 2 个 shared_ptr 或 unique_ptr 与原始指针。


推荐阅读