I have a class which is essentially a std::vector<T> with some additional functionality. The class has find(const T& value ) method which will return index of first occurence of value or -1:
int my::find(const T& value) {
auto iter = std::find(this->data.begin(), this->data.end(), value);
if (iter == this->data.end())
return -1;
return std::distance(this->data.begin(), iter);
}
all good. I then wanted to create a find() overload which took in a arbitrary predicate instead of a value - I have tried:
int my::find(const std::function<bool(const T&)>& pred) {
auto iter = std::find(this->data.begin(), this->data.end(), pred);
...
}
and also:
template <typename P>
int my::find(P&& pred) {
auto iter = ...
}
But both cases fail to compile because "the compiler" tries to find pred in a vector of pred type values, instead of applying pred to the values, i.e. when when I have instantiated my<int> I get compiler errors like:
/usr/include/c++/5/bits/predefined_ops.h:194:17: error: no match for ‘operator==’ (operand types are ‘int’ and ‘const std::function<bool(const int&)>’)
{ return *__it == _M_value; }
The algorithm std::find will always treat its third argument as a value that is compared to elements in the given sequence by operator==. The predicate you pass in can't be compared to the T instances of the class, hence the compiler error.
You are looking for std::find_if (overloads #3-4), which takes a predicate as the third argument.
When you use a predicate, use std::find_if.
int my::find(const std::function<bool(const T&)>& pred) {
auto iter = std::find_if(this->data.begin(), this->data.end(), pred);
...
}
In keeping with function names in the standard library, I think you should change your function name also to find_if when you use a predicate.
int my::find_if(const std::function<bool(const T&)>& pred) {
auto iter = std::find_if(this->data.begin(), this->data.end(), pred);
...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With