The problem here is a fairly subtle one. Before C++ 20, lambdas are not default constructible, but from C++ 20 on, they are. So looking at this:
priority_queue<int, vector<int>, decltype(comp)> pq;
we can see that pq
only knows the type of your comparator and will need to instantiate that type itself. But, before C++20, it cannot because the language doesn't support it.
So, there are two solutions to this, both equally easy:
Add -std=c++20
to your compiler switches.
Change that line of code to:
priority_queue<int, vector<int>, decltype(comp)> pq { comp };
And in fact for option 2, since you are (also) initialising comp
inline, you also need:
static constexpr auto comp = [] (int n1, int n2) { return n1 > n2; };
or:
static inline auto comp = [] (int n1, int n2) { return n1 > n2; };
Both of which need C++17 or later.
Now you have passed as instance of comp
to priority_queue
's (alternative) constructor and so it has what it needs to get the job done.
The reason that std::greater
works is that it's a just a normal functor that std::priority_queue
can construct an instance of when it needs to.
I would also say that it's worth reading this.
And just to round off, the nice thing about using C++ 20 is that, for one-off cases, you can do things like this:
std::priority_queue<int, std::vector<int>, decltype ([] (int n1, int n2) { return n1 > n2; })> pq;
Which keeps it all neat and tidy.