C++打印对象优先队列报错及运算符重载正确性咨询
你遇到的错误原因与修复方案
咱先解决那个编译报错的问题:priority_queue::top()返回的是const引用(const Horse&)——这是标准库的设计,因为优先队列的堆顶元素不能被随意修改,否则会直接破坏堆的结构。而你的print()成员函数没有声明为const,const对象是不能调用非const成员函数的,所以编译器才会抛出“discards qualifiers”的错误。
修复超简单,给print()加上const修饰就行:
void print() const { // 这里加const,表明这个函数不会修改对象成员 std::cout<<"name: "<< horseName<<std::endl; }
关于operator<重载的正确性分析
你写的重载版本有两个可以优化的点,其中一个还涉及逻辑正确性:
1. 你的原版本问题
bool operator < (Horse h) const { if (h.win < win) return true; return false; }
- 参数传递问题:直接传
Horse h会触发对象拷贝,改成const Horse& h可以避免不必要的拷贝,提升效率; - 逻辑反了:默认
priority_queue是大顶堆(用std::less<T>做比较器,堆顶是“优先级最高”的元素)。你的逻辑是:当h.win < win(也就是当前对象的win比传入对象大)时,返回true,这会让priority_queue认为当前对象的优先级更低,最终导致win值小的马排在前面,和你“按win顺序打印(大的优先)”的预期完全相反。
2. 修正后的正确版本
如果想要让win值大的马优先出现在堆顶,正确的成员函数重载应该是:
bool operator<(const Horse& h) const { return win < h.win; // 当当前对象的win小于h的win时,当前对象优先级更低 }
这样,当a.win=3、b.win=5时,a < b返回true,priority_queue会把a放在b的后面,堆顶就是win更大的b,符合你的预期。
3. 你看到的全局函数版本问题
你看到的那种写法是错误的——全局的operator<不能加const修饰(const是成员函数的专属修饰符,全局函数没有this指针,不需要也不允许加)。正确的全局版本应该是:
bool operator<(const Horse& lhs, const Horse& rhs) { return lhs.win < rhs.win; // 逻辑和成员函数版本一致 }
修正后的完整可运行代码
#include <iostream> #include <vector> #include <queue> #include <string> struct Horse { std::string horseName; int win; void print() const { std::cout << "name: " << horseName << std::endl; } bool operator<(const Horse& h) const { return win < h.win; // win值大的优先 } }; class Horses { public: std::vector<Horse> horses; void printPriorityQ(std::priority_queue<Horse> q) { while (!q.empty()) { q.top().print(); q.pop(); } std::cout << std::endl; } void testing(); }; void Horses::testing() { Horse h; h.horseName = "max"; h.win = 3; horses.push_back(h); h.horseName = "bob"; h.win = 5; horses.push_back(h); h.horseName = "alice"; h.win = 4; horses.push_back(h); std::priority_queue<Horse> winner; for (size_t i=0; i<horses.size(); i++) winner.push(horses[i]); printPriorityQ(winner); // 预期输出:name: bob → name: alice → name: max } int main() { Horses h; h.testing(); return 0; }
内容的提问来源于stack exchange,提问作者william_
相关产品推荐
相关产品推荐

