具有 lambda 函数错误的优先级队列

Posted

技术标签:

【中文标题】具有 lambda 函数错误的优先级队列【英文标题】:Priority Queue with lambda function error 【发布时间】:2018-04-18 07:48:40 【问题描述】:

这一切都在一个类中。 B 类持有一个列表。

class A
   bool compare = [](const B& lhs, const B& rhs)
     return lhs.list.size() >= rhs.list.size();
   ;

   priority_queue<B, vector<B>, decltype(compare)> pq(compare);
;

我在 pq 上遇到任何错误。我对 lambda 函数非常不熟悉,所以我不知道如何解决这个函数。

错误:比较不是类型

【问题讨论】:

题外话:为什么不只是一个常规的、普通的、静态的成员函数?这里没有需要使用 lambda。 @StoryTeller 这个比较函数将有多个返回值。因此,我将使用 switch 语句访问 A 类中的成员,该成员将决定比较将返回什么返回值。编辑:除非您知道比较器有多个返回的方法。 这个 lambda(假设它是“固定的”)也不会帮助你做到这一点...... @Plays4u 然后你需要访问函数内部的A 实例,所以你需要一个成员函数和/或一个捕获lambda。 在我看来,如果你需要替换它所代表的函数,在这里使用 lambda 是有意义的。 @StoryTeller:“固定”的 lambda 是没用的,不是吗? lamdbas 可以在一个方面的实现之间进行更改。 【参考方案1】:

成员comparebool,不是函数,它的值是true。从您的 lambda 类型到 bool(*)(const B&amp;, const B&amp;) 的隐式转换,然后从函数指针类型到 bool 的转换。如果您要向捕获列表中添加任何内容,则该行将失败,因为有状态 lambda 不会转换为函数指针。

你不能声明数据成员auto,所以如果你想让它成为一个lambda,它就不能在类范围内。但你不需要它,静态函数可以正常工作。

class A
   static bool compare(const B& lhs, const B& rhs) 
     return lhs.list.size() >= rhs.list.size();
   ; 

   std::priority_queue<B, std::vector<B>, decltype(compare)> pq;
public:
   A():pq(compare)
;

【讨论】:

【参考方案2】:

有几件事需要改变。首先,lambda 声明很奇怪。 Lambda 在最后给出它们的返回值(虽然我认为这是允许的,但在我看来可能被解读为试图将 lambda 分配给 bool 变量。

其次,我无法对捕获 lambda 的实际类型的 auto 或类似关键字执行相同操作,因为这意味着静态 constexpr 与您所拥有的相去甚远。

因此,我明确地为 lambda 提供了一个好的类型(请注意,lambda 的类型总是很奇怪,因此在许多情况下,如果您想要可读的错误消息和这几乎从来都不是问题。如果您不知道签名,您很可能必须对其进行模板化。但是,带有 lambda 的类也将被模板化,没有问题。

最后,用元素初始化队列是不正确的,因为可能很难以正确的顺序构造所有对象。因此,初始化已经移到了A的构​​造函数中。

这是我的更正:

#include<queue>
#include<list>
#include<vector>
#include<functional>

using namespace std;

struct B
  std::list<int> list;
;

class A
   function<bool(const B&, const B&)> compare = [](const B& lhs, const B& rhs) ->bool
     return lhs.list.size() >= rhs.list.size();
   ; 

   std::priority_queue<B, vector<B>, decltype(compare)> pq;
   A():pq(compare)
;


int main()


最后请注意,我不喜欢将 B 的成员命名为 list,因为 list 也是类型。

【讨论】:

Lambda 类型并不“奇怪”,它们只是未命名。 list 不是B::list 的类型,它是std::list。尽管如此,list 仍然是一个对象的坏名

以上是关于具有 lambda 函数错误的优先级队列的主要内容,如果未能解决你的问题,请参考以下文章

c++优先级队列priority_queue使用lambda表达式出错问题

具有自定义比较器的最小优先级队列

通过引用传递自定义优先级队列

将多个项目添加到具有固定大小数组的优先级队列时出错

优先级队列中的不同元素

python[数据]--队列,堆,优先级队列