我有一个名为Foo
的类,每个Foo
对象都有一个名为yVal
的方法。我想要的是按Foo
Foo.yVal()
对象的优先级队列
我在Foo
中重载了operator>和operator <:
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()
的升序对优先级队列进行排序。相反,它只是以某种未知的随机顺序对它们进行排序。我在operator>和operator <中放置了一个cout语句,它们甚至都没有被调用。因此,我尝试使用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);
但这给了我“非静态数据成员声明为自动”错误。
理想情况下,我希望通过更大的<>和运算符重载来实现此目的。如果不能,请告诉我我对lambda做错了什么(不太熟悉lambda,因此希望尽可能避免使用它们。)
我也尝试过使用仿函数,但是同样,仿函数上的auto给我同样的“非静态数据成员声明为auto”错误。
答案 0 :(得分:0)
您获得了随机顺序未知,因为当您拥有greater<T>
进行以下操作
// pseudocode
cmp(T lhs, T rhs) {
return lhs > rhs;
}
您的代码中的T
是什么? T
是unique_ptr<Foo>
,C ++库中有operator>(unique_ptr<>,unique_ptr<>)
吗?
是的,它是see here,并且此运算符在比较时使用unique_ptr::get
方法:
// Psuedocode when greater used:
cmp (unique_ptr<Foo>& lhs, unique_ptr<Foo>& rhs)
{
lhs.get () > rhs.get()
}
unique_ptr::get
返回什么?它返回指向Foo
的指针,
因此,您正在比较指向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
方法。
编辑:带有功能对象的版本。
// 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;