我正在尝试使用不同的比较器类编写一个包含两个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
结构中,并且一步就可以到达另一集合中的相应迭代器,但这感觉有些过头了。
好吧,我不可能是第一个遇到这种情况的人。是否有一种既定的方法可以使用多个标准来轻松导航保留一组元素?特别是在没有进行过度工程的疯狂的情况下?
答案 0 :(得分:1)
首先,您要进行异构查找:能够找到具有给定Element
值BarStruct
的{{1}},而无需构造虚拟{{1 }}。这可以通过将以下myBar
重载添加到Element(myBar)
(和等效地operator()
)来实现:
CriterionBar
注意:您的比较运算符必须是CriterionFoo
成员函数!
此外,您need to add和bool 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