使用 lamdas 的引用传递的稳定排序自定义比较器给出编译错误
Stable sort custom comparator using pass by reference with lamdas gives compile error
https://leetcode.com/problems/move-zeroes/ 正在解决这个问题。
但这不会编译。
void moveZeroes(vector<int>& nums) {
stable_sort(nums.begin(), nums.end(),[](int& a, int& b){
if(a == 0 && b != 0){
return false;
}
if(a != 0 && b == 0){
return true;
}
else {return false;}
});
}
但是如果我们使用按值传递
(int a, int b)
它编译。
根本问题是什么??
lambda 可以将其参数作为引用。问题在于,在您的示例中,它们不是 const-ref,并且 std::stable_sort
传递常量值,
comp
[...] The signature of the
comparison function should be equivalent to the following:
bool cmp(const Type1 &a, const Type2 &b);
While the signature does not need to have const &
, the function must not modify the objects passed to it and must be able
to accept all values of type (possibly const
) Type1
and Type2
regardless of value category (thus, Type1 &
is not allowed, nor
is Type1
unless for Type1
a move is equivalent to a copy (since
C++11)).
无法转换为 non-const ref。只需声明 lambda 取 const int&
即可:
stable_sort(nums.begin(), nums.end(),[](const int& a, const int& b) {
// ...
});
编译器错误是一个致命的漏洞(为简洁起见截断了文件名):
bits/predefined_ops.h:177:11: error: no match for call to ‘(moveZeroes(std::vector<int>&)::<lambda(int&, int&)>) (int&, const int&)’
177 | { return bool(_M_comp(*__it, __val)); }
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
bits/predefined_ops.h:177:11: note: candidate: ‘bool (*)(int&, int&)’ <conversion>
bits/predefined_ops.h:177:11: note: conversion of argument 3 would be ill-formed:
bits/predefined_ops.h:177:11: error: binding reference of type ‘int&’ to ‘const int’ discards qualifiers
https://leetcode.com/problems/move-zeroes/ 正在解决这个问题。 但这不会编译。
void moveZeroes(vector<int>& nums) {
stable_sort(nums.begin(), nums.end(),[](int& a, int& b){
if(a == 0 && b != 0){
return false;
}
if(a != 0 && b == 0){
return true;
}
else {return false;}
});
}
但是如果我们使用按值传递
(int a, int b)
它编译。
根本问题是什么??
lambda 可以将其参数作为引用。问题在于,在您的示例中,它们不是 const-ref,并且 std::stable_sort
传递常量值,
comp
[...] The signature of the
comparison function should be equivalent to the following:bool cmp(const Type1 &a, const Type2 &b);
While the signature does not need to have
const &
, the function must not modify the objects passed to it and must be able to accept all values of type (possiblyconst
)Type1
andType2
regardless of value category (thus,Type1 &
is not allowed, nor isType1
unless forType1
a move is equivalent to a copy (since C++11)).
无法转换为 non-const ref。只需声明 lambda 取 const int&
即可:
stable_sort(nums.begin(), nums.end(),[](const int& a, const int& b) {
// ...
});
编译器错误是一个致命的漏洞(为简洁起见截断了文件名):
bits/predefined_ops.h:177:11: error: no match for call to ‘(moveZeroes(std::vector<int>&)::<lambda(int&, int&)>) (int&, const int&)’
177 | { return bool(_M_comp(*__it, __val)); }
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
bits/predefined_ops.h:177:11: note: candidate: ‘bool (*)(int&, int&)’ <conversion>
bits/predefined_ops.h:177:11: note: conversion of argument 3 would be ill-formed:
bits/predefined_ops.h:177:11: error: binding reference of type ‘int&’ to ‘const int’ discards qualifiers