3

I'm trying to use the C++ STL priority queue with a custom type and comparator, but no matter how I put it, I keep getting an error.

Does anyone know what the issue might be? I'm trying to copy the syntax from documentation but nothing has been working...

The custom type is a pointer to the ListNode class used in LeetCode:

 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */

Within my class, I have a static comparison function:

static bool compare(ListNode* n1, ListNode* n2) {
    return n1->val < n2->val;
}

And I am trying to initialize the priority queue like this:

priority_queue<ListNode*, vector<ListNode*>, decltype(compare)> pq(compare);

But I keep getting an error, saying:

In file included from prog_joined.cpp:1:
In file included from ./precompiled/headers.h:55:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/queue:64:
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_queue.h:485:18: error: data member instantiated with function type 'bool (ListNode *, ListNode *)'
      _Compare   comp;
                 ^
Line 137: Char 73: note: in instantiation of template class 'std::priority_queue<ListNode *, std::vector<ListNode *, std::allocator<ListNode *>>, bool (ListNode *, ListNode *)>' requested here
        priority_queue<ListNode*, vector<ListNode*>, decltype(compare)> pq(compare);
                                                                        ^
1 error generated.

Thanks!

2 Answers 2

6

You should specify a function pointer type, but not a function type as the template argument for priority_queue.

Change

priority_queue<ListNode*, vector<ListNode*>, decltype(compare)> pq(compare);

to

priority_queue<ListNode*, vector<ListNode*>, decltype(compare)*> pq(compare);
//                                                            ^
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you very much! Just to understand it better, why does it have to be a function pointer?
@JakeSanders Function pointers could be passed to priority_queue, which stores it as object and uses it to compare elements. While functions can't. In priority_queue<ListNode*, vector<ListNode*>, decltype(compare)*> pq(compare);, compare decays to function pointer and then gets passed to the constructor of priority_queue, same as priority_queue<ListNode*, vector<ListNode*>, decltype(compare)*> pq(&compare);.
priority_queue<ListNode*, vector<ListNode*>, decltype(&compare)> pq(compare) also works.
2

Instead of declaring and defining a static function, you can define a lambda.

auto compare = [](ListNode* n1, ListNode* n2) {
    return n1->val < n2->val;
};

Since the type of lambda is resolved automatically by the compiler, then you would not need to think about things like a parameter's type being a function pointer or a function etc.

decltype(...) will resolve to a callable object anyways.

3 Comments

Would I still need to use "decltype" and everything if I do it this way? How would I declare the priority queue then?
priority queue initialization becomes correct if you use an auto lambda, instead of writing a function. if you use a declared/defined function with decltype, what you need to tell the priority queue is you are passing a function pointer (which is callable).
you do not need to specify the last two types. they would work with vector and an auto lambda by default.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.