1

一緒にマージする必要がある 2 つのブースト侵入セットがあります。押し付けがましいセットをブーストmap_old.m_old_attributesするためにマージする必要がある押し付けがましいセットがありますm_map_new_attributes

void DataTest::merge_set(DataMap& map_old)
{

    // merge map_old.m_old_attributes set into m_map_new_attributes
}

これを行う最善の方法は何ですか?マージを実行できる関数が見つかりませんか? 最近、boost intrusive セットの使用を開始しましたが、マージを実行できる定義済みのメソッドを見つけることができませんでしたか、それとも間違っているのでしょうか?

4

1 に答える 1

1

実際、侵入セットは別の獣です。それらは要素の割り当てを管理しません。

したがって、マージするときは、それが何を意味するかを決定する必要があります。合理的な解釈は、コンテナー内に含まれる要素を DataMapに移動したいということです。map_old

これは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());
}

更新または、少しトリッキーな iterator-erase-loop を使用して、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());
}

もちろん、マージ操作のさまざまなセマンティクスを考え出すことができます (これは、「移動」ではなく「コピー」に似ています)。

于 2015-05-05T19:32:37.223 に答える