1

I am trying to create a priority queue with a custom comparator but the following code gives me a compile error:

    auto comparator = [](std::pair<std::vector<int>, File&> const &a, std::pair<std::vector<int>, File&> const &b) {
      return a.first.front() > b.first.front();  
};

     std::priority_queue<std::pair<std::vector<uint64_t>, File&>,
      std::vector<std::pair<std::vector<uint64_t>, File&>>,
      decltype(comparator)> pq;

This is the error I am getting:

In template: no matching constructor for initialization of 'std::priority_queue<std::pair<std::vector, moderndbs::File &>, std::vector<std::pair<std::vector, moderndbs::File &>>, (lambda at

3
  • Your comparator knows how to compare values of type std::pair<std::vector<int>, File&>, but you are trying to use it to compare values of a different type std::pair<std::vector<uint64_t>, File&> Commented May 2, 2021 at 23:23
  • This does not fix the problem. Commented May 2, 2021 at 23:27
  • Since you only pass the type of comparator to the priority queue, but not the instance itself, the queue has to default-construct one. However, lambdas are not default-constructible before C++20. You need to compile with C++20 support enabled for this to work, or else pass comparator to pq's constructor, as in std::priority_queue<...> pq{comparator} Commented May 2, 2021 at 23:27

1 Answer 1

1

There's a mismatch in your question, between uint64_t and int. Assuming that this is squared away:

You need at least C++20 in order to compile the shown code. Prior to C++20, lambdas are not default-constructible, and you attempting to default-construct your std::priority_queue.

You need to explicitly pass the comparator to the constructor. Tested with gcc 10, with -std=c++17:

#include <queue>
#include <functional>
#include <vector>
#include <cstdint>

class File{};

void foo()
{
    auto comparator = [](std::pair<std::vector<int>,
                 File &> const &a,
                 std::pair<std::vector<int>,
                 File &> const &b) {
        return a.first.front() > b.first.front();
    };

    std::priority_queue<std::pair<std::vector<int>,
                      File &>,
                std::vector<std::pair<std::vector<int>,
                          File &>
                    >,
                decltype(comparator)> pq{comparator};
}

This fails with with a default-constructor pq. gcc 10 compiles the default-constructed pq with -std=c++20.

P.S.: consider replacing the File & with std::reference_wrapper, unless you really intend to do what the File & in std::pair will really do.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, Sam! It works now :) File is a custom file class here, can you briefly mention what reference_wrapper does? I will only read these files later, which one should I use in this case :)

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.