我有一些功能来找到一个值:
struct FindPredicate { FindPredicate(const SomeType& t) : _t(t) { } bool operator()(SomeType& t) { return t == _t; } private: const SomeType& _t; }; bool ContainsValue(std::vector& v, SomeType& valueToFind) { return find_if(v.begin(), v.end(), FindPredicate(valueToFind)) != v.end(); }
现在我想编写一个函数来检查向量的所有成员是否满足该谓词:
bool AllSatisfy(std::vector& v) { /* ... */ }
一种解决方案是使用该std::count_if
算法.
有没有人知道一个涉及否定谓词的解决方案?
最好的解决方案是使用STL功能库.通过从中派生谓词unary_function
,您将能够使用该not1
函数,该函数正是您所需要的(即否定一元谓词).
这是你如何做到这一点:
struct FindPredicate : public unary_function{ FindPredicate(const SomeType& t) : _t(t) {} bool operator()(const SomeType& t) const { return t == _t; } private: const SomeType& _t; }; bool AllSatisfy(std::vector & 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& v) { return find_if(v.begin(), v.end(), NotFindPredicate(valueToFind)) == v.end(); }
或者你可以做得更好并写一个模板函子否定器,如:
templatestruct Not { Not(Functor & f) : func(f) {} template bool operator()(ArgType & arg) { return ! func(arg); } private: Functor & func; };
您可以使用如下:
bool AllSatisfy(std::vector& v, SomeType& valueToFind) { FindPredicate f(valueToFind); return find_if(v.begin(), v.end(), Not (f)) == v.end(); }
当然,后一种解决方案更好,因为您可以将Not struct重用于您想要的每个仿函数.
看到std库functor not1,它返回一个仿函数,它不是你给它的函子返回的逻辑.
你应该可以这样做:
bool AllSatisfy(std::vector& v, SomeType& valueToFind) { return find_if(v.begin(), v.end(), not1(FindPredicate(valueToFind))) != v.end(); }