使用 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