使用带有多个比较条件的std :: set的容器

时间:2018-08-03 12:04:02

标签: c++ data-structures stl

我正在尝试使用不同的比较器类编写一个包含两个std::set且具有相同元素的容器。这是我的简化看法:

struct Element
{
    // foo and bar are immutable to prevent messing set order up.
    FooStruct const foo;
    BarStruct const bar;
    int someVar;

    Element(FooStruct foo);
    Element(BarStruct bar);
};

class CriterionFoo
{
    // Sorts according to member foo.
    bool operator()(Element* const& arg0, Element* const& arg1);
};

class CriterionBar
{
    // Sorts according to member bar.
    bool operator()(Element* const& arg0, Element* const& arg1);
};

class ElementContainer
{
    typedef std::set<Element*, CriterionFoo> FooSortedSet;
    typedef std::set<Element*, CriterionBar> BarSortedSet;

    FooSortedSet fooSortedSet;
    BarSortedSet barSortedSet;

    // fooSortedSet.find(&Element(myFoo))
    Element* findElement(FooStruct myFoo);
    // barSortedSet.find(&Element(myBar))
    Element* findElement(BarStruct myBar);

    // Inserts in both sets.
    void insert(Element* element);

    // Enter total alienation and existential crisis...
    void erase(BarStruct myBar);
    void erase(FooStruct myFoo);
};

我要做的就是创建一个集合包装器,该包装器以log(n)复杂度查找具有两个不同搜索条件的成员。 ElementContainer::erase方法可以很容易地找到任一准则的[Foo|Bar]SortedSet::iterator,但是无论如何我都必须天真地遍历另一个准则(这几乎胜过了所有要点)。再说一次,我可以将[Foo|Bar]SortedSet::const_iterator引用放在Element结构中,并且一步就可以到达另一集合中的相应迭代器,但这感觉有些过头了。

好吧,我不可能是第一个遇到这种情况的人。是否有一种既定的方法可以使用多个标准来轻松导航保留一组元素?特别是在没有进行过度工程的疯狂的情况下?

1 个答案:

答案 0 :(得分:1)

首先,您要进行异构查找:能够找到具有给定ElementBarStruct的{​​{1}},而无需构造虚拟{{1 }}。这可以通过将以下myBar重载添加到Element(myBar)(和等效地operator())来实现:

CriterionBar

注意:您的比较运算符必须是CriterionFoo成员函数!

此外,您need to addbool operator()(Element* const& lhs, BarStruct const& rhs) const; bool operator()(BarStruct const& lhs, Element* const& rhs) const; 使集合考虑这些其他比较选项(并将相应的重载添加到const中)。例如:

is_transparent

这并非绝对必要,但比您当前正在做的虚拟find要好得多。

通过两个using is_transparent = void; 操作从这两个集合中删除的实际步骤很简单:

Element