Home > Blockchain >  Default constructed std::priority_queue with a lambda
Default constructed std::priority_queue with a lambda

Time:10-05

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);
  • Related