Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to clear a `priority_queue` that uses user-defined compare?

How to clear a priority_queue that uses user-defined compare?

From https://en.cppreference.com/w/cpp/container/priority_queue, I reduced the use of priority_queue to the case I need (= queue with user-defined compare)

>> cat test.cpp 
#include <functional>
#include <queue>
#include <vector>
#include <iostream>
#include <utility>

auto queue_cmp = [](std::pair<int, double> const& lhs,
                    std::pair<int, double> const& rhs) {
    return lhs.second > rhs.second; // Custom order.
};
typedef std::priority_queue<std::pair<int, double>,
                            std::vector<std::pair<int, double>>,
                            decltype(queue_cmp)> custom_queue;

template<typename T>
void print_queue(T q) { // NB: pass by value so the print uses a copy
    int s = 0;
    while(!q.empty()) {
        std::pair<int, double> elem = q.top();
        std::cout << s << ": " << elem.first << ", " << elem.second << std::endl;
        q.pop();
        s++;
    }
    std::cout << '\n';
}

int main() {
    custom_queue q(queue_cmp);
    for (int n = 10; n < 20; n++) {
        double val = static_cast <double>(rand())/(static_cast<double>(RAND_MAX));
        q.push(std::pair<int, double>(n, val));
    }
    print_queue(q);
    //q = custom_queue(queue_cmp);
}

This runs OK

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>> g++ -o test test.cpp 

>> ./test 
0: 15, 0.197551
1: 18, 0.277775
2: 16, 0.335223
3: 11, 0.394383
4: 19, 0.55397
5: 17, 0.76823
6: 12, 0.783099
7: 13, 0.79844
8: 10, 0.840188
9: 14, 0.911647

Now I need to reset q so, following priority queue clear method, I uncomment the last line in test.cpp… And get this compilation error as if I get this correctly, copy constructors are deleted on lamdba:

>> g++ -o test test.cpp 
test.cpp: In function ‘int main()’:
test.cpp:34:31: error: use of deleted function ‘std::priority_queue<std::pair<int, double>, std::vector<std::pair<int, double> >, <lambda(const std::pair<int, double>&, const std::pair<int, double>&)> >& std::priority_queue<std::pair<int, double>, std::vector<std::pair<int, double> >, <lambda(const std::pair<int, double>&, const std::pair<int, double>&)> >::operator=(std::priority_queue<std::pair<int, double>, std::vector<std::pair<int, double> >, <lambda(const std::pair<int, double>&, const std::pair<int, double>&)> >&&)’
   34 |     q = custom_queue(queue_cmp);
      |                               ^
In file included from /usr/include/c++/12/queue:64,
                 from test.cpp:2:
/usr/include/c++/12/bits/stl_queue.h:498:11: note: ‘std::priority_queue<std::pair<int, double>, std::vector<std::pair<int, double> >, <lambda(const std::pair<int, double>&, const std::pair<int, double>&)> >& std::priority_queue<std::pair<int, double>, std::vector<std::pair<int, double> >, <lambda(const std::pair<int, double>&, const std::pair<int, double>&)> >::operator=(std::priority_queue<std::pair<int, double>, std::vector<std::pair<int, double> >, <lambda(const std::pair<int, double>&, const std::pair<int, double>&)> >&&)’ is implicitly deleted because the default definition would be ill-formed:
  498 |     class priority_queue
      |           ^~~~~~~~~~~~~~
/usr/include/c++/12/bits/stl_queue.h:498:11: error: use of deleted function ‘<lambda(const std::pair<int, double>&, const std::pair<int, double>&)>&<lambda(const std::pair<int, double>&, const std::pair<int, double>&)>::operator=(const<lambda(const std::pair<int, double>&, const std::pair<int, double>&)>&)’
test.cpp:7:19: note: a lambda closure type has a deleted copy assignment operator
    7 | auto queue_cmp = [](std::pair<int, double> const& lhs,
      |                   ^

Is there a way to reset q in this case?

EDIT


bool queue_cmp(std::pair<int, double> const& lhs,
               std::pair<int, double> const& rhs) {
    return lhs.second > rhs.second; // Custom order.
};


Doesn’t help

>Solution :

Not in C++17.

C++20 gives capture-less lambdas a default constructor. But in earlier language versions, the constructor is deleted.

Really, you should not be using a lambda. Just use a named struct.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading