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