【问题标题】:C++ priority queue in ascending order by specific method for unique pointers to objectsC ++优先级队列按特定方法按升序排列,以获取指向对象的唯一指针
【发布时间】:2018-11-04 17:28:29
【问题描述】:

我有一个名为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

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”的错误。

【问题讨论】:

  • 你不是已经问过这个了吗?
  • @NeilButterworth 是的,但在答案中我不明白该仿函数应该用于什么?抱歉,我可以再澄清一下吗?
  • 如果您不理解答案,您应该在原始问题中要求澄清,而不是发布新问题。
  • @NeilButterworth 你能否重新发布答案并澄清它。对不起,我是新人。

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


【解决方案1】:

你得到了未知的随机顺序,因为当你有greater&lt;T&gt; 执行以下操作

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

您的代码中的T 是什么? Tunique_ptr&lt;Foo&gt;,C++ 库中有 operator&gt;(unique_ptr&lt;&gt;,unique_ptr&lt;&gt;) 吗? 没错,就是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&lt;Foo&gt; ? 您正在存储 unique_ptr&lt;Foo&gt;,因此您的 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 的实例无法复制,您必须通过引用传递它们。 也可以使用-&gt; 运算符来访问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;

【讨论】:

  • 我仍然收到“非静态数据成员声明为自动”错误。没有自动你能做到这一点吗?
  • @JoshCarter 你用的是什么编译器? c++11开启了吗?
  • @JoshCarter 您在代码中的哪个位置创建cmp 对象?作为班级成员或职能部门的成员?
  • 作为班级成员,紧跟在public:关键字之后
  • @JoshCarter 尝试:std::function&lt;bool (const std::unique_ptr&lt;Foo&gt;&amp;,const std::unique_ptr&lt;Foo&gt;&amp;)&gt; cmp = ... 如果此更改没有帮助,您应该编辑您的问题并展示您如何定义 priority_queue 和 cmp。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-16
  • 1970-01-01
相关资源
最近更新 更多