简体   繁体   English

STL多集设置插入顺序C ++

[英]STL multiset setting insertion order C++

I am using a multiset to store a collection of objects ordered, I am using operator< to establish the order criteria, but I am doing something wrong because when I iterate through the multiset printing a trace, I can see that they are not ordered at all.... I'm really blocked with this issue... 我正在使用多重集来存储有序对象的集合,我正在使用operator <来建立顺序标准,但是我做错了,因为当我遍历多重集打印跟踪时,我可以看到它们在以下位置不是有序的全部...。这个问题真的让我受阻...

I try to simplify my code here: 我尝试在这里简化代码:

class CellSearch
{
    public:
        bool operator<(const CellSearch & C) const;
        int getF() const        { return _G + _H; }
    private:
        int _G;
        int _H;
}
...
bool CellSearch::operator< (const CellSearch& C) const
{
    return (this->getF() < C.getF());
}

the way I declare the multiset is: 我声明多重集的方式是:

std::multiset<CellSearch*> myOpenList;

and I insert a new element this way: 然后我以这种方式插入一个新元素:

....
CellSearch *actualSearch = new CellSearch(start);
addOpenList(actualSearch, myOpenList);

And here is the function: 这是函数:

void Grid::addOpenList(CellSearch* actual, std::multiset<CellSearch*>& openList)
{
    openList.insert(actual);
}

Is my first time using multiset...actually is my first container that is not a vector :) Can you see something wrong here? 我是第一次使用多重集吗?实际上是我的第一个容器不是向量:)您在这里看到错误了吗?

I tried to summarize the code, I hope not too much... 我试图总结一下代码,希望不要太多...

Your multiset is storing pointers to objects. 您的多重集正在存储指向对象的指针 As a result, for comparison it compares pointers , rather than the objects itself. 结果,为了进行比较,它比较的是指针 ,而不是对象本身。

To make it work in current form, you need to put objects themselves into multiset. 为了使它以当前形式工作,您需要将对象本身放入多集。 Another option is to provide a custom comparator to set, which would know to dereference a pointer and compare the actual object - but this is inferior in this case, as I do not see any reason to store pointers at all. 另一个选择是提供一个自定义比较器进行设置,该比较器将知道要取消对指针的引用并比较实际的对象,但是在这种情况下这是次等的,因为我根本看不到任何存储指针的理由。

It is also better to implement operator < as a free-function rather than the class member. 最好将operator <作为自由函数而不是类成员来实现。

If you are set on having pointers in your container, this is how you should do it: 如果您打算在容器中使用指针,则应该这样做:

template<class KEY>
struct pointer_compare {
    bool operator()(const KEY* lhs, const KEY* rhs) const {
        return *lhs < *rhs;
    }
}

std::multiset<Search*, pointer_compare<Search>> myOpenList

The problem is that you're working not with the set of CellSearch objects, but pointers to them, which makes the comparator work with pointers. 问题在于您不是在使用CellSearch对象集,而是在使用指向它们的指针,这使得比较器可以使用指针。

Here is the generic solution which you could reuse for other pointer comparisons: 这是通用的解决方案,您可以将其重用于其他指针比较:

template<class T>
struct PointerComparator {
    bool operator()(const T *a, const T *b) const {
        return *a < *b;
    }
};

std::multiset<CellSearch*, PointerComparator<CellSearch> > myOpenList;

This way you still have your operator < defined for CellSearch . 这样,您仍然可以为CellSearch定义operator <

You can define a cell less functor like this: 您可以这样定义一个少单元函子:

class cmpCell
{
    bool operator()(CellSearch* a, CellSearch* b)
    {
        return *a < *b;
    }
};

And then use it when declare the multiset: 然后在声明多集时使用它:

std::multiset<CellSearch*, cmpCell> myOpenList;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM