我正在寻找std::set
的替代品。我需要它来支持更多操作,然后std::set
:
将元素从一个集合移动到另一个集合而不需要“创建新的> copy->删除旧的”。
在某个位置设置分割以获得两组(使用std::list splice
可以获得类似的行为)
设置操作(如联合),无需不必要的复制。如果我只需要设置C并且不再需要A和B,那么std::set_union
会将集合A和B中的元素复制到集合C,效率很低。
是否有任何支持这些操作的实现,或者我需要自己编写一个?
答案 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
允许合并两个集合而不复制或移动任何元素,只更新内部指针。