I have some function to find a value:
struct FindPredicate
{
FindPredicate(const SomeType& t) : _t(t) {
}
bool operator()(SomeType& t) {
return t == _t;
}
private:
const SomeType& _t;
};
bool ContainsValue(std::vector<SomeType>& v, SomeType& valueToFind) {
return find_if(v.begin(), v.end(), FindPredicate(valueToFind)) != v.end();
}
Now I would like to write a function that checks if all members of a vector satisfy that predicate:
bool AllSatisfy(std::vector<SomeType>& v) {
/* ... */
}
One solution is to use the std::count_if
algorithm.
Does anyone know a solution that involves negating the predicate?
The best solution is to use the STL functional library. By deriving your predicate from unary_function<SomeType, bool>
, you'll then be able to use the not1
function, which does precisely what you need (i.e. negating a unary predicate).
Here is how you could do that :
struct FindPredicate : public unary_function<SomeType, bool>
{
FindPredicate(const SomeType& t) : _t(t) {}
bool operator()(const SomeType& t) const {
return t == _t;
}
private:
const SomeType& _t;
};
bool AllSatisfy(std::vector<SomeType>& v, SomeType& valueToFind)
{
return find_if(v.begin(),
v.end(),
not1(FindPredicate(valueToFind))) == v.end();
}
If you want to roll your own solution (which is, IMHO, not the best option...), well, you could write another predicate that is the negation of the first one :
struct NotFindPredicate
{
NotFindPredicate(const SomeType& t) : _t(t) {
}
bool operator()(SomeType& t) {
return t != _t;
}
private:
const SomeType& _t;
};
bool AllSatisfy(std::vector<SomeType>& v) {
return find_if(v.begin(),
v.end(),
NotFindPredicate(valueToFind)) == v.end();
}
Or you could do better and write a template functor negator, like :
template <class Functor>
struct Not
{
Not(Functor & f) : func(f) {}
template <typename ArgType>
bool operator()(ArgType & arg) { return ! func(arg); }
private:
Functor & func;
};
that you could use as follow :
bool AllSatisfy(std::vector<SomeType>& v, SomeType& valueToFind)
{
FindPredicate f(valueToFind);
return find_if(v.begin(), v.end(), Not<FindPredicate>(f)) == v.end();
}
Of course, the latter solution is better because you can reuse the Not struct with every functor you want.
See the std library functor not1, it returns a functor that is the logical not of whatever the functor you give it would return.
You should be able to do something like:
bool AllSatisfy(std::vector<SomeType>& v, SomeType& valueToFind) {
return find_if(v.begin(), v.end(), not1(FindPredicate(valueToFind))) != v.end();
}
The first time I used not1
I wondered why it wasn't simply called not
.
The answer surprised me a bit (see comment).
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