I was just trying to swap the data between the two priority queues and got this error. I also did some googling and still don't know what's wrong here.
#include <queue>
class Node
{
public:
int idx;
};
auto greater = []( const Node& a, const Node& b) {return a.idx > b.idx; };
using QUEUE = std::priority_queue<Node, std::vector<Node>, decltype(greater)>;
void foo(QUEUE& a)
{
QUEUE b(greater);
a.swap(b);
}
int main()
{
}
Here's the full error message:
Error C2280 ' < lambda_07efac20ebfa61cc8bb35aebd7d81f7c> &<< lambda_07efac20ebfa61cc8bb35aebd7d81f7c>>::operator =(const << lambda_07efac20ebfa61cc8bb35aebd7d81f7c>> &)': attempting to reference a deleted function
The implementation of std::swap
in stdlibc++ (and, most likely, standard library for Visual Studio) uses old-fashioned assignments:
swap(_Tp& __a, _Tp& __b)
{
// concept requirements
__glibcxx_function_requires(_SGIAssignableConcept<_Tp>)
_Tp __tmp = __a;
__a = __b;
__b = __tmp;
}
On the contrary, libcxx implements it using std::move
:
swap(_Tp& __x, _Tp& __y) _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value &&
is_nothrow_move_assignable<_Tp>::value)
{
_Tp __t(_VSTD::move(__x));
__x = _VSTD::move(__y);
__y = _VSTD::move(__t);
}
In order to swap objects of type std::priority_queue
you have to swap their comparators, which are represented as a lambda in your code. Swapping lambda in stdlibc++ is impossible due to deleted copy assignment operator.
By the way, there is no need to use a lambda since your capture list is empty. A simple function will do the job.
bool greater(const Node& a, const Node& b) {return a.idx > b.idx;};
using QUEUE = std::priority_queue<Node, std::vector<Node>, decltype(&greater)>;
void foo(QUEUE&& a)
{
QUEUE b(&greater);
a.swap(b);
}
Alternatively, you can replace a lambda with a callable object which has move assignment.