具有 lambda 比较器错误的 C + + 优先级队列

我有下面的错误代码,我试图在 VC2010中编译,但我得到的错误 C2974,这只有在我包含 lambda 表达式时才会发生,所以我猜它与此有关。

typedef pair<pair<int, int>, int> adjlist_edge;
priority_queue< adjlist_edge , vector<adjlist_edge>,
[](adjlist_edge a, adjlist_edge b) -> bool {
if(a.second > b.second){ return true; } else { return false; }
}> adjlist_pq;

我知道模板定义的形式是正确的

priority_queue<int , vector<int>, greater<int>> pq;

果然有效。知道我哪里做错了吗?Lambda 是不是有什么明显的问题我可能忽略了?感谢您的阅读!

58406 次浏览

priority_queue将比较器作为模板参数。Lambda 函数是对象,因此不能用作模板参数(只有极少数类型可以,其中包括整数类型)。

你可以在这里尝试使用 decltype:

priority_queue< adjlist_edge , vector<adjlist_edge>,
decltype( [](adjlist_edge a, adjlist_edge b) -> bool {
if(a.second > b.second){ return true; } else { return false; }
})>
adjlist_pq( [](adjlist_edge a, adjlist_edge b) -> bool {
if(a.second > b.second){ return true; } else { return false; }
} );

如果找不到(一定会的) ,可以使用 function<>:

priority_queue< adjlist_edge , vector<adjlist_edge>,
function<bool(adjlist_edge,adjlist_edge)> >
adjlist_pq( [](adjlist_edge a, adjlist_edge b) -> bool {
if(a.second > b.second){ return true; } else { return false; }
} );

首先定义 lambda 对象,然后使用 decltype将其传递给模板的类型,并将其直接传递给构造函数。

auto comp = []( adjist a, adjlist b ) { return a.second > b.second; };
priority_queue< adjlist_edge , vector<adjlist_edge>, decltype( comp ) >
adjlist_pq( comp );

接受的答案回答 怎么做,将 lambda 表达式定义为一个自定义 Compare 对象。 我想解决这个问题的另一个方面: 为什么在定义 pq 时会失败:

typedef pair<pair<int, int>, int> adjlist_edge;
priority_queue< adjlist_edge , vector<adjlist_edge>,
[](adjlist_edge a, adjlist_edge b) -> bool {
if(a.second > b.second){ return true; } else { return false; }}> adjlist_pq;

为什么在构造优先级队列时必须将 lambda 作为参数传递?原因就在于 Lambda 表达式没有缺省构造函数。因此,如果在构造优先级队列时没有提供它,那么 lambda 表达式的“假定存在的缺省构造函数”将被调用。显然,它会失败。

关于你的问题: 比较对象(lambda 或者 function 对象)是否有一个缺省构造函数决定了区别。

下面是一个使用优先级队列构建小堆的示例。我使用了一个 lambda 来定义比较器,给出了由 vector<ListNode *> &lists定义的链表

// This comparator will be used to build minheap.
auto comp = [&](ListNode *a, ListNode *b) {
return a->val > b->val;
};


// This priority queue is the min heap
priority_queue<ListNode *, vector<ListNode *>, decltype(comp)> pq(comp);