Лучшим решением является использование STL functional library. Получив предикат от 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();
}
Конечно, последнее решение лучше, потому что вы можете повторно использовать Не-структуру с каждым функтора вы хотите.
И тогда вы можете добавить шаблон функции, как прокладка в SGI люди сделали, чтобы вернуть Не объект без необходимости указывать его тип. –
xtofl
2008-11-05 19:55:17