确实,侵入式套装是一种不同的野兽。他们不管理他们的元素分配。
因此,在合并时,您需要确定这意味着什么。我想说一个合理的解释是您希望将容器内包含的元素移动map_old
到 DataMap 中。
这将map_old
留空。这是一个这样的算法:
template <typename Set>
void merge_into(Set& s, Set& into) {
std::vector<std::reference_wrapper<Element> > tmp(s.begin(), s.end());
s.clear(); // important! unlinks the existing hooks
into.insert(tmp.begin(), tmp.end());
}
更新或者,您可以通过使用稍微复杂的迭代器擦除循环(小心迭代变异容器)来使用 O(1) 内存复杂度来实现:Live On Coliru也是如此
for (auto it = s.begin(); it != s.end();) {
auto& e = *it;
it = s.erase(it);
into.insert(e);
}
看见Live On Coliru
#include <boost/intrusive/set.hpp>
#include <boost/intrusive/set_hook.hpp>
#include <string>
#include <vector>
#include <functional>
#include <iostream>
namespace bive = boost::intrusive;
struct Element : bive::set_base_hook<> {
std::string data;
Element(std::string const& data = "") : data(data) {}
bool operator< (Element const& rhs) const { return data < rhs.data; }
bool operator==(Element const& rhs) const { return data ==rhs.data; }
};
using Set = bive::set<Element>;
template <typename Set>
void merge_into(Set& s, Set& into) {
std::vector<std::reference_wrapper<Element> > tmp(s.begin(), s.end());
s.clear(); // important! unlinks the existing hooks
into.insert(tmp.begin(), tmp.end());
}
int main() {
std::vector<Element> va {{"one"},{"two"},{"three"},{"four"},{"five"},{"six"},{"seven"},{"eight"},{"nine"} };
Set a;
for(auto& v : va) a.insert(v);
std::vector<Element> vb {{"two"},{"four"},{"six"},{"eight"},{"ten"} };
Set b;
for(auto& v : vb) b.insert(v);
assert(9==a.size());
assert(5==b.size());
merge_into(a, b);
assert(a.empty());
assert(10==b.size());
}
当然,您可以为合并操作提出不同的语义(这更类似于“复制”而不是“移动”)