STL порядок вставки мультимножества настроек C++

Я использую мультимножество для хранения коллекции упорядоченных объектов, я использую оператор<, чтобы установить критерии порядка, но я делаю что-то не так, потому что, когда я выполняю итерацию по многосетевой печати трассировки, я вижу, что они не упорядочены в все.... я действительно заблокирован этой проблемой...

Я пытаюсь упростить мой код здесь:

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());
}

способ, которым я объявляю мультимножество:

std::multiset<CellSearch*> myOpenList;

и я вставляю новый элемент таким образом:

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

А вот и функция:

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

Я впервые использую мультимножество... на самом деле это мой первый контейнер, который не является вектором:).

Я попытался обобщить код, надеюсь, не слишком много...

3 ответа

Решение

Ваш мультимножество хранит указатели на объекты. В результате для сравнения сравниваются указатели, а не сами объекты.

Чтобы он работал в текущей форме, вам нужно поместить объекты в мультимножество. Другой вариант - предоставить настраиваемый компаратор для установки, который будет знать, как разыменовывать указатель и сравнивать реальный объект - но в этом случае это хуже, так как я не вижу никакой причины хранить указатели вообще.

Также лучше реализовать operator < как свободная функция, а не член класса.

Если вы настроены на наличие указателей в вашем контейнере, вот как вы должны это сделать:

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

Проблема в том, что вы работаете не с набором CellSearch объекты, но указатели на них, что заставляет компаратор работать с указателями.

Вот общее решение, которое вы можете использовать для других сравнений указателей:

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

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

Таким образом, у вас еще есть свой operator < определено для CellSearch,

Вы можете определить функтор без ячейки следующим образом:

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

А затем используйте его, когда объявляете мультимножество:

std::multiset<CellSearch*, cmpCell> myOpenList;
Другие вопросы по тегам