我有一个
.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
的深层副本?
我对阅读器线程代码的访问权限有限,并且只有在绝对必要的情况下才允许我进行更改
侵入式列表库不提供独立的容器。我们期望您拥有类似
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
现在是可复制的,并且您拥有强异常安全的所有权。