C++ Priority_Queue with Lambda Comparator Error

C++ priority_queue with lambda comparator error

First define the lambda object, then pass it to the template's type using decltype and also pass it directly to the constructor.

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

C++ priority_queue using map with lambda comparator error

First, your capture list of your lambda (the square brackets) is empty, I guess there should be

[&m]

there ?

Next, if you search for the operator[] of std::map, you will find that this can only operate on non-const maps (https://en.cppreference.com/w/cpp/container/map/operator_at). Your lambda is likely being invoked with a const map instead. So try using

return m.at(a) < m.at(b);

C++ how to declare an array of priority_queue with customed comparator

You can do the following to achieve what you want:

bool PriorByRaw(Klass const & a, Klass const & b) { return a.raw_hash > b.raw_hash; }

class KlassCompare
{
public:
bool operator() (Klass const & a, Klass const & b) const
{
return PriorByRaw(a, b);
}
};
priority_queue<Klass, vector<Klass>, KlassCompare> pq[10];

Several comments:

  1. I replaced passing the Klass objects by const& instead of by value, since this is more efficient. Is there any reason you passed it by value ?

  2. The main issue is to replace the lambda with a comparator class with operator(). Using the lambda and decltype(prior) requires the compiler to construct a new instance of a lambda which is not allowed.
    MSVC gives the following error for using the lambda:

    "error C3497: you cannot construct an instance of a lambda"

    You can look C3497 up if you'd like to get more info.

Priority queue lambda comparator and normal comparator

cmp is a lambda. It's an object with a () operator.

But cmp2() is a function.

You can't use a function as a callable type, but you can use a function pointer as a callable type, in that case you must use decltype(&cmp) to get a function pointer type:

    priority_queue<array<int, 2>, vector<array<int, 2>>, decltype(&cmp2)> pq2(&cmp2);

Priority Queue With a Custom Comparator No Matching Constructor

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.

c++: priority_queue: lambda-expression in template-argument

You cant have a lambda (which is an object) in a type template declaration (where a type is needed. Do instead:

auto lambda =  [](vector<int> &v1, vector<int> &v2){
return v1[2] > v2[2];
};
priority_queue< vector<int>, vector<vector<int>>,decltype(lambda)> pq{lambda};

We also need to pass the lambda since it is not default constructible.

Form C++20 on, we can do the following:

priority_queue< vector<int>, vector<vector<int>>,decltype([](vector<int> &v1, vector<int> &v2){
return v1[2] > v2[2];
};
)> pq{};

Here there come two new featurs of lambdas into play. First that you can take the type of it directly (formally: In C++17 you cannot have a lambda-expression in unevaluated context) and second that lambdas are default constructible. But right now, that is not yet possible.



Related Topics



Leave a reply



Submit