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

时间:2018-11-04 17:28:30

标签: c++ priority-queue unique-ptr

我有一个名为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”错误。

1 个答案:

答案 0 :(得分:0)

您获得了随机顺序未知,因为当您拥有greater<T> 进行以下操作

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

您的代码中的T是什么? Tunique_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:

哪些对象存储在队列中? Foounique_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;