I mistakenly omitted the compare
argument when defining a std::priority_queue
:
#include <queue>
int main()
{
constexpr auto cmp{[](int a, int b) { return a > b; }};
std::priority_queue<int, std::vector<int>, decltype(cmp)> pq;
}
, and it compiled successfully and worked properly when I used it to implement Dijkstra's algorithm.
Then I realized that I passed only the type information of cmp
when constructing pq
.
However, the code compiles only if --std=c 20
flag is used.
I skimmed the priority_queue reference on cppreference.com
but couldn't find any notice about a change that occurred since C 20.
I used the following version of g
:
g (Ubuntu 10.3.0-1ubuntu1~20.04) 10.3.0
Is this an intended behavior since C 20, and if so, what has affected this change?
CodePudding user response:
The change happened on lambdas.
If no captures are specified, the closure type has a defaulted default constructor. Otherwise, it has no default constructor (this includes the case when there is a capture-default, even if it does not actually capture anything). (Since C 20)
Before C 20, lambda closure types are not DefaultConstructible, the comparator object can't be default-constructed in the default constructor of std::priority_queue
, then you have to pass the lambda object to the constructor of std::priority_queue
taking comparator object.
constexpr auto cmp{[](int a, int b) { return a > b; }};
std::priority_queue<int, std::vector<int>, decltype(cmp)> pq(cmp);