【问题标题】:Why is STL priority queue incorrectly sorrting my class objects为什么 STL 优先级队列错误地对我的类对象进行排序
【发布时间】:2019-10-25 08:52:40
【问题描述】:

我重载了< 运算符,如图所示,但每次运行程序时,我的类对象似乎都是随机排序的。

class Node
{
int decimal_value
public:
    Node(int decimal) : decimal_value(decimal)
    {}
    friend bool operator<(const Node& p1, const Node& p2);
};

 bool operator<(const Node& p1, const Node& p2)
{
    return p1.decimal_value < p2.decimal_value;
}

int main()
{
    Node* n1= new Node(5);
    Node* n2 = new Node(4);

    priority_queue<Node*> my_q;
    my_q.push(n1);
    my_q.push(n2);
}

这可能是因为我使用了指向节点的指针而不是节点本身吗?如果是这样,我该如何解决?

【问题讨论】:

  • 在创建minimal reproducible example 向我们展示时,请确保它复制了您遇到的问题,并且不包含任何其他不相关的错误。
  • 您的运算符重载与指针的优先级队列无关。他们正在使用股票指针价值比较的面值进行比较。将自定义比较器类型作为队列的附加参数。
  • 是的,问题很可能是因为您有一个指针队列,因此将调用的比较运算符是bool operator&lt;(Node*, Node*)
  • 查看link
  • priority_queue&lt;Node&gt; 有什么问题?如果你真的必须存储指针,你应该存储智能指针(除非其他人负责释放它们)

标签: c++ stl polymorphism priority-queue


【解决方案1】:

priority_queue&lt;Node*&gt; my_q; 将比较 Node* 类型的元素进行排序,它不会为您取消引用这些指针并调用您的重载运算符。并且不相关指针的比较具有un定义的行为,但在您的情况下不会产生有用的结果。

当你修复了这个,会有另一个bug:你从来没有初始化decimal_value,所以它的值是未定义/随机的。

一种解决方案是明确指定一个比较器:

struct MyComparator {
    bool operator()(const Node*l, const Node*r) const {
        return l->decimal_value < r->decimal_value;
    }
};

std::priority_queue<Node*, std::vector<Node*>, MyComparator> q;

【讨论】:

  • 不相关指针的比较有defined behavior(虽然只是部分排序)。减法does not.
  • 我明白了,那么有没有办法使用 priority_queue 对指针指向的内容进行排序?
  • @Risen,我加了一个小例子:)
  • @MaxLanghof 嗯,我记得不相关的指针之间的指针比较也是 UB。 C ++ 11可能会改变吗?不幸的是,目前无法使用旧标准...
  • @Aconcagua 在 C++11 中,它是明确定义的(尽管大多未指定):timsong-cpp.github.io/cppwp/n3337/expr.rel#2n1905 from 2005 类似。让我看看哪里有更旧的草稿...
猜你喜欢
  • 2013-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-13
  • 1970-01-01
相关资源
最近更新 更多