创建侵入列表的深层副本

问题描述 投票:0回答:1

我有一个

.hpp
看起来与此类似

#include <boost/intrusive/list.hpp>
#include <unordered_map>

using namespace boost::intrusive;

struct Tag;
using Hook = list_base_hook< tag<Tag> >;

class Str : public Hook
{
public:
    Str(int n) : n_(n) {}
    Str(const Str& s) : n_(s.n_) {}

    int n_;
};

using List = list< Str, cache_last<true>, base_hook<Hook> >;
using Map = std::unordered_map<std::string, List>;

并且我有 2 个线程正在使用

Map
,即写入器和读取器,但我无法长时间锁定写入器线程,因此我需要创建
Map
的深层副本,以便读取线程进行工作。我的问题是侵入性列表是可移动的但不可复制,所以我尝试像这样动态创建列表

int deep_copy_map(Map& orig, Map& copy)
{
    for (auto& it: orig) {
        List list_copy;
        for (auto& it1: it.second) {
            list_copy.push_back(*(new Str{it1}));
        }
        copy.insert({ it.first, std::move(list_copy) });
    }
}

但现在我正在泄漏

Str
对象,因为侵入性列表不会破坏其元素。所以我接下来尝试将其添加到我的
.hpp

class List_ : public List
{
public:
    ~List_()
    {
        while (!this->empty())
        {
            Str* node = &this->front();
            this->pop_front();
            delete node;
        }
    }
};

using Map = std::unordered_map<std::string, List_>;

并将副本更新为

int deep_copy_map(Map& orig, Map& copy)
{
    for (auto& it: orig) {
        List_ list_copy;
        for (auto& it1: it.second) {
            list_copy.push_back(*(new Str{it1}));
        }
        copy.insert({ it.first, std::move(list_copy) });
    }
}

但现在我收到错误

error: no matching function for call to ‘std::unordered_map<std::__cxx11::basic_string<char>, List_>::insert(<brace-enclosed initializer list>)’
    copy.insert({ it.first, std::move(list_copy) });

有没有办法在不泄漏内存的情况下创建

Map
的深层副本?

我对阅读器线程代码的访问权限有限,并且只有在绝对必要的情况下才允许我进行更改

c++ boost-intrusive
1个回答
0
投票

侵入式列表库不提供独立的容器。我们期望您拥有类似

std::vector
之类的所有权,并将其全部包装在您需要的界面中。

using bi = boost::intrusive;

class List
{
    using Intrusive = bi::list< Str, bi::cache_last<true>, bi::base_hook<Hook> >;
    std::vector<Str> elems;
    Intrusive list;
public:
    Intrusive::iterator begin() { return list.begin(); }
    Intrusive::iterator end() { return list.end(); }

    Intrusive::iterator insert(Intrusive::iterator where, const Str & what) { return list.insert(where, elems.push_back(what)); }

    // other members to taste
};

using Map = std::unordered_map<std::string, List>;

有了这个,

Map
现在是可复制的,并且您拥有强异常安全的所有权。

© www.soinside.com 2019 - 2024. All rights reserved.