带有lambda比较器错误的C ++ priority_queue

时间:2011-04-27 16:57:31

标签: c++ stl lambda c++11 priority-queue

我有以下错误的代码,我试图在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有什么明显的错误我可能会忽略吗?谢谢你的阅读!

4 个答案:

答案 0 :(得分:58)

首先定义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 );

答案 1 :(得分:15)

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; }
            } );

答案 2 :(得分:0)

接受的答案回答了如何来定义具有lambda表达式的priority_queue作为自定义的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或函数对象)是否具有默认构造函数才有所不同。

答案 3 :(得分:0)

以下是使用优先级队列构建minheap的示例。给定vector<ListNode *> &lists

给出的链表,我已经使用lambda定义了比较器。
// 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);