I'm learning C++, and I'm trying to implement a binary search function that finds the first element for which a predicate holds. The function's first argument is a vector and the second argument is a function that evaluates the predicate for a given element. The binary search function looks like this:
template <typename T> int binsearch(const std::vector<T> &ts, bool (*predicate)(T)) { ... } This works as expected if used like this:
bool gte(int x) { return x >= 5; } int main(int argc, char** argv) { std::vector<int> a = {1, 2, 3}; binsearch(a, gte); return 0; } But if I use a lambda function as a predicate, I get a compiler error:
search-for-a-range.cpp:20:5: error: no matching function for call to 'binsearch' binsearch(a, [](int e) -> bool { return e >= 5; }); ^~~~~~~~~ search-for-a-range.cpp:6:27: note: candidate template ignored: could not match 'bool (*)(T)' against '(lambda at search-for-a-range.cpp:20:18)' template <typename T> int binsearch(const std::vector<T> &ts, ^ 1 error generated. The above error is generated by
binsearch(a, [](int e) -> bool { return e >= 5; }); What's wrong? Why is the compiler not convinced that my lambda has the right type?
std::lower_bound(which you are reimplementing) takes a pair of iterators rather than a container as its argument. This allows it to work with any kind of container, or a subset of a container, or even ranges the Standard Library designers haven't yet thought of. When you have your code working overstd::vectorI strongly advise looking to make it more general in this way; I promise you'll learn something!std::find_if(), notstd::lower_bound(). Both are instructive, and implementing your own is good exercise, so the rest still stands.