交换优先级队列时尝试引用已删除的函数错误
Attempting to reference a deleted function error when swapping priority queues
我正试图在两个优先级队列之间交换数据并得到了这个错误。我也做了一些谷歌搜索,但仍然不知道这里出了什么问题。
#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()
{
}
完整的错误信息如下:
Error C2280 ' < lambda_07efac20ebfa61cc8bb35aebd7d81f7c> &<<
lambda_07efac20ebfa61cc8bb35aebd7d81f7c>>::operator =(const <<
lambda_07efac20ebfa61cc8bb35aebd7d81f7c>> &)': attempting to reference
a deleted function
Lambda 没有赋值运算符,而 swap() 使用赋值。它将尝试对队列中保存的更大的 lambda 使用赋值。
stdlibc++ 中 std::swap
的实现(很可能是 Visual Studio 的标准库)使用老式赋值:
swap(_Tp& __a, _Tp& __b)
{
// concept requirements
__glibcxx_function_requires(_SGIAssignableConcept<_Tp>)
_Tp __tmp = __a;
__a = __b;
__b = __tmp;
}
相反,libcxx使用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);
}
为了交换 std::priority_queue
类型的对象,您必须交换它们的比较器,这些比较器在您的代码中表示为 lambda。由于删除了复制赋值运算符,无法在 stdlibc++ 中交换 lambda。
顺便说一句,没有必要使用 lambda,因为您的捕获列表是空的。一个简单的函数就可以完成这项工作。
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);
}
或者,您可以将 lambda 替换为具有移动赋值的可调用对象。
我正试图在两个优先级队列之间交换数据并得到了这个错误。我也做了一些谷歌搜索,但仍然不知道这里出了什么问题。
#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()
{
}
完整的错误信息如下:
Error C2280 ' < lambda_07efac20ebfa61cc8bb35aebd7d81f7c> &<< lambda_07efac20ebfa61cc8bb35aebd7d81f7c>>::operator =(const << lambda_07efac20ebfa61cc8bb35aebd7d81f7c>> &)': attempting to reference a deleted function
Lambda 没有赋值运算符,而 swap() 使用赋值。它将尝试对队列中保存的更大的 lambda 使用赋值。
stdlibc++ 中 std::swap
的实现(很可能是 Visual Studio 的标准库)使用老式赋值:
swap(_Tp& __a, _Tp& __b)
{
// concept requirements
__glibcxx_function_requires(_SGIAssignableConcept<_Tp>)
_Tp __tmp = __a;
__a = __b;
__b = __tmp;
}
相反,libcxx使用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);
}
为了交换 std::priority_queue
类型的对象,您必须交换它们的比较器,这些比较器在您的代码中表示为 lambda。由于删除了复制赋值运算符,无法在 stdlibc++ 中交换 lambda。
顺便说一句,没有必要使用 lambda,因为您的捕获列表是空的。一个简单的函数就可以完成这项工作。
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);
}
或者,您可以将 lambda 替换为具有移动赋值的可调用对象。