具有 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】:
成员compare
是bool
,不是函数,它的值是true
。从您的 lambda 类型到 bool(*)(const B&, const B&)
的隐式转换,然后从函数指针类型到 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 函数错误的优先级队列的主要内容,如果未能解决你的问题,请参考以下文章