C++ Reuse Lambda as Compare function in `std::priority_queue`

When working with std::priority_queue, I tried to clear the contents of the priority queue like this:

#include <iostream>
#include <queue>
#include <vector>

using std::cout;
using std::priority_queue;
using std::vector;

int main() {

    const auto comp = [](int a, int b) {
        return a > b;
    };

    auto a = priority_queue<int, vector<int>, decltype(comp)>(comp);

    a.push(10);
    a.push(9);
    a.push(8);

    // 3
    cout << a.size() << '\n';

    a = priority_queue<int, vector<int>, decltype(comp)>(comp);

    // 0
    cout << a.size() << '\n';

    return 0;

}

When compiling with Clang, I got an error:

In file included from tmp.cpp:1:
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/queue:455:39: error: no viable overloaded '='
        {c = _VSTD::move(__q.c); comp = _VSTD::move(__q.comp); return *this;}
                                 ~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~
tmp.cpp:19:7: note: in instantiation of member function 'std::priority_queue<int, std::vector<int>, const (lambda at tmp.cpp:9:23)>::operator=' requested here
    a = priority_queue<int, vector<int>, decltype(comp)>(comp);
      ^
tmp.cpp:9:23: note: candidate function (the implicit copy assignment operator) not viable: 'this' argument has type 'std::priority_queue<int, std::vector<int>, const (lambda at tmp.cpp:9:23)>::value_compare' (aka 'const (lambda at tmp.cpp:9:23)'), but method is not marked const
    const auto comp = [](int a, int b) {
                      ^
1 error generated.

Why would this give me an error? And is there any way to fix it? Thanks.

>Solution :

decltype(comp) is a const type, const auto comp, that makes the priority_queue member variable storing comp to be constant, thus can’t be re-assigned.

You might want

priority_queue<int, vector<int>, remove_cv_t<decltype(comp)>>(comp);

Or

auto comp = [](int a, int b) {
    return a > b;
};

The copy assignment operator for lambdas are implicitly deleted. The fix:

std::function<bool(int, int)> comp = [](int a, int b) {
    return a > b;
};

Leave a Reply