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