STL multiset 设置插入顺序 C++

STL multiset setting insertion order C++

我正在使用 multiset 来存储有序对象的集合,我正在使用 operator< 来建立顺序标准,但是我做错了,因为当我遍历 multiset 打印跟踪时,我可以看到他们根本没有订购....我真的被这个问题所困扰...

我尝试在这里简化我的代码:

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

我是第一次使用 multiset...实际上是我第一个不是向量的容器 :) 你能看出这里有什么问题吗?

我试着总结了代码,希望不要太多...

您的多重集正在存储指向对象的指针。因此,为了比较,它比较 指针 ,而不是对象本身。

要使其以当前形式工作,您需要将 对象 本身放入多重集。另一种选择是提供一个自定义比较器来设置,它知道取消引用指针并比较实际对象 - 但在这种情况下这是次等的,因为我根本没有看到任何存储指针的理由。

最好将 operator < 作为自由函数而不是 class 成员来实现。

如果您打算在容器中使用指针,那么您应该这样做:

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;

这样您仍然可以为 CellSearch 定义 operator <

你可以像这样定义一个无单元仿函数:

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

然后在声明多重集时使用它:

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