I am not very familiar with C++, and am confused about how a comparator works.
The below code is how I can find the position I want to insert a new interval:
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
vector<vector<int>> intervals; // = ...
vector<int> newInterval; // = ...
// ...
auto comp = [](const vector<int>& a, const vector<int>& b) { return a[0] < b[0]; };
auto it = upper_bound(intervals.begin(), intervals.end(), newInterval, comp);
}
Hen I try to remove const
, it will get a compile error.
Why do I need to add const
for this custom comparator?
From the std::upper_bound
documentation regarding the comparator (comp
):
The signature of the predicate function should be equivalent to the following:
bool pred(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).
(thus, Type1 & is not allowed, nor is Type1 unless for Type1 a move is equivalent to a copy(since C++11))
(emphasis is mine)
Since the comparator must be able to accept const
values (and must not modify them), the trivial solution is to use const &
. The other alternative is to accept the objects by value, which is relevant only for simple types like int
.
Note:
As @IgorTandetnik commented in practice only the first object must be const, in all 3 major compilers (gcc, clang, MSVC) - see demo. But this is true only in the case that non-const iterators are used (like in the code you posted). If you use const iterators (cbegin()
, cend()
) both objects in the comparators must be const
in order to compile.
In any case it's good practice to have a const &
for both objects in the comparator.