替代std :: set(能够将元素从一个集合移动到另一个集合)

时间:2012-12-14 09:57:01

标签: c++ stl set

我正在寻找std::set的替代品。我需要它来支持更多操作,然后std::set

  1. 将元素从一个集合移动到另一个集合而不需要“创建新的> copy->删除旧的”。

  2. 在某个位置设置分割以获得两组(使用std::list splice可以获得类似的行为)

  3. 设置操作(如联合),无需不必要的复制。如果我只需要设置C并且不再需要A和B,那么std::set_union会将集合A和B中的元素复制到集合C,效率很低。

  4. 是否有任何支持这些操作的实现,或者我需要自己编写一个?

3 个答案:

答案 0 :(得分:2)

对于第1点和第1点3,您可以直接在set<shared_ptr>中使用set或其他智能指针代替商店对象。在这种情况下,您应该实现

bool operator<(shared_ptr<T> const & a, shared_ptr<T> const & b)

对于第2点,由于set中没有索引,因此不会仅仅通过索引确定这样的方法。但是,您可以在ruby中使用filter之类的内容。这里谓词可以是函数,函数对象或闭包。

remove_copy_if(foo.begin(), foo.end(), back_inserter(bar), some_predicator);

答案 1 :(得分:2)

尝试使用std::set建议你做的事情的问题是我不相信你可以移出一个值。这是因为set迭代器只返回const引用,以阻止您更改值并破坏内部结构。您可以const_cast绕过这条路,但我不推荐它。即使您采用这种方法,您仍然可以在树中分配节点,并且您无法避免这种开销。

如果您决定实现自己的支持移动值的集合,您应该能够获得Boost :: Intrusive库(http://www.boost.org/doc/libs/1_52_0/doc/html/ intrusive.html)为保持一组排序值而进行繁重的工作。您需要实现用于管理对象生存期的代码,但这比构建RB树实现更容易。

我为地图实现了类似的东西,将节点存储在std::list中。这允许在地图之间移动元素而不复制节点结构或存储的值。如果我有时间,我会尝试整理并在此发布。

答案 2 :(得分:2)

我和std::set有同样的问题,而C ++ 11,C ++ 14似乎没有任何理智的方法。然而,在C ++ 17中,有两个新成员添加到std::set,看起来非常有前景。 std::set::extract允许从集合中提取整个节点。被移除的节点允许获得对基础值的非const引用,从而有效地允许将元素移出集合。它也可以插入到另一个集合中,而无需复制或移动基础值。 std::set::merge允许合并两个集合而不复制或移动任何元素,只更新内部指针。