Лучшее решение - использовать функциональную библиотеку STL . Получив свой предикат из unary_function<SomeType, bool>
, вы сможете использовать функцию not1
, которая делает именно то, что вам нужно (то есть отрицание унарного предиката).
Вот как это можно сделать:
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();
}
Если вы хотите развернуть свое собственное решение (что, IMHO, не лучший вариант ...), вы можете написать еще один предикат, который является отрицанием первого:
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();
}
Или вы могли бы сделать лучше и написать шаблонный отрицатель функтора, например:
template <class Functor>
struct Not
{
Not(Functor & f) : func(f) {}
template <typename ArgType>
bool operator()(ArgType & arg) { return ! func(arg); }
private:
Functor & func;
};
, который вы можете использовать следующим образом:
bool AllSatisfy(std::vector<SomeType>& v, SomeType& valueToFind)
{
FindPredicate f(valueToFind);
return find_if(v.begin(), v.end(), Not<FindPredicate>(f)) == v.end();
}
Конечно, последнее решение лучше, потому что вы можете повторно использовать структуру Not с каждым необходимым вам функтором.