-1

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...

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...

Breikdans
  • 67
  • 6

3 Answers3

4

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.

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
SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • thank you for the advices!! :) anyway, could you please give an example of how could make a comparison dereferencing the pointer to compare the object? – Breikdans Apr 05 '16 at 20:38
  • thank you very much! I will consider the option of not to store pointers, but it was very interesting for mw to learn also the way to compare it dereferencing pointers :) – Breikdans Apr 05 '16 at 20:52
1

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.

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.

dreamzor
  • 5,795
  • 4
  • 41
  • 61
0

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;
alangab
  • 849
  • 5
  • 20