我有一些函数来查找值:
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(); }
现在,我想编写一个函数来检查向量的所有成员是否都满足该谓词:
bool AllSatisfy(std::vector<SomeType>& v) { /* ... */ }
一种解决方案是使用该std::count_if算法。
std::count_if
有谁知道涉及否定谓词的解决方案?
最好的解决方案是使用STL功能库。通过从导出谓词unary_function<SomeType, bool>,您将可以使用该not1函数,该函数恰好满足您的需要(即,否定一元谓词)。
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(); }
如果您想推出自己的解决方案(恕我直言,不是最好的选择…),那么,您可以编写另一个谓词,即对第一个谓词的否定:
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 结构。