为啥 STL 优先级队列错误地对我的类对象进行排序
Posted
技术标签:
【中文标题】为啥 STL 优先级队列错误地对我的类对象进行排序【英文标题】: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<(Node*, Node*)
。
查看link
priority_queue<Node>
有什么问题?如果你真的必须存储指针,你应该存储智能指针(除非其他人负责释放它们)
【参考方案1】:
priority_queue<Node*> 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#2。 n1905 from 2005 类似。让我看看哪里有更旧的草稿...以上是关于为啥 STL 优先级队列错误地对我的类对象进行排序的主要内容,如果未能解决你的问题,请参考以下文章