Stable sort custom comparator using pass by reference with lamdas gives compile error

223 Views Asked by At

https://leetcode.com/problems/move-zeroes/ was solving this question. But this doesnot compile.

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;}
        });
    }

However if we use pass by value that is (int a, int b) it compiles. What is the underlying issue??

1

There are 1 best solutions below

1
On BEST ANSWER

The lambda can take its arguments as refs. The problem is that in your example, they are not const-ref, and std::stable_sort passes const values,

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)).

which cannot be converted to non-const ref. Simply declare the lambda to take const int& instead:

stable_sort(nums.begin(), nums.end(),[](const int& a, const int& b) {
    // ...
  });

The compiler error is a dead giveaway (filename truncated for brevity):

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