C++优先级队列,按对象的唯一指针的特定方法升序排列

C++ priority queue in ascending order by specific method for unique pointers to objects

本文关键字:方法 升序 排列 指针 唯一 队列 对象 C++ 优先级      更新时间:2023-10-16

我有一个名为Foo的类,每个Foo对象都有一个称为yVal的方法。我想要的是按Foo.yVal()升序排列的Foo对象的优先级队列

我使运算符>和运算符<在Foo中到此:

bool operator> (const Foo &f){
return yVal() > f.yVal();
}
bool operator< (const Foo &f){
return yVal() < f.yVal();
}

所以我有以下代码:

priority_queue<unique_ptr<Foo>, vector<unique_ptr<Foo>>, greater<unique_ptr<Foo>> > Queue;

但这并不是按照Foo.yVal()的升序对优先级队列进行排序。相反,它只是按照某种未知的随机顺序对它们进行排序。我在运算符>和运算符<他们甚至没有接到电话。所以我试着用lambda来代替:

auto cmp = [](Foo left, Foo right) {return left.xVal() > right.xVal();};
priority_queue<unique_ptr<Foo>, vector<unique_ptr<Foo>>, decltype(cmp) > Queue(cmp);

但这给了我一个"非静态数据成员声明为auto"的错误。

理想情况下,我希望与更大的<>以及操作员过载。如果不能,请有人告诉我lambda有什么问题(对lambda不太熟悉,如果可能的话,我会尽量避免(。

我也尝试过使用函子,但函子上的auto再次给了我相同的"非静态数据成员声明auto"错误。

您得到了未知的随机顺序,因为当您有greater<T>时执行以下操作

// pseudocode
cmp(T lhs, T rhs) {
return lhs > rhs;
}

您的代码中的T是什么?T就是unique_ptr<Foo>,C++库中有operator>(unique_ptr<>,unique_ptr<>)吗?是的,在这里可以看到,这个操作符在比较时使用unique_ptr::get方法:

// Psuedocode when greater used:
cmp (unique_ptr<Foo>& lhs, unique_ptr<Foo>& rhs)
{
lhs.get () > rhs.get()
}

unique_ptr::get返回什么?它返回指向CCD_ 15的指针,因此您正在比较指向Foo实例的指针。结果是不可预测的。代码编译并执行,但它并没有达到您所期望的效果。


如何修复lambda:

队列中存储了哪些对象?Foo还是unique_ptr<Foo>?您正在存储unique_ptr<Foo>,因此lambda的参数应声明为采用此类型。

auto cmp = [](const unique_ptr<Foo>& left, const unique_ptr<Foo>& right) 
{                   ^^^^^^^^^^^^^^^^
return left->yVal() > right->yVal();
};             ^^
priority_queue<unique_ptr<Foo>, vector<unique_ptr<Foo>>, decltype(cmp) > Queue(cmp);

因为unique_ptr的实例无法复制,所以必须通过引用传递它们。也可以使用->运算符访问yVal方法。


EDIT:带有函数对象的版本。

// comparator as function object with overloaded operator()
struct Cmp {
bool operator()(const std::unique_ptr<Foo>& left, const std::unique_ptr<Foo>& right) const {
return left->xVal() > right->xVal();
}
};
class YourClass {
public:
std::priority_queue<std::unique_ptr<Foo>, std::vector<std::unique_ptr<Foo>>, Cmp> Queue;