And*_*dre 14 c++ algorithm stl
我有一些功能来找到一个值:
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();
}
Run Code Online (Sandbox Code Playgroud)
现在我想编写一个函数来检查向量的所有成员是否满足该谓词:
bool AllSatisfy(std::vector<SomeType>& v) {
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
一种解决方案是使用该std::count_if算法.
有没有人知道一个涉及否定谓词的解决方案?
Luc*_*lle 20
最好的解决方案是使用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();
}
Run Code Online (Sandbox Code Playgroud)
如果你想推出自己的解决方案(也就是恕我直言,不是最好的选择...),那么,你可以编写另一个谓词,这是第一个的否定:
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();
}
Run Code Online (Sandbox Code Playgroud)
或者你可以做得更好并写一个模板函子否定器,如:
template <class Functor>
struct Not
{
Not(Functor & f) : func(f) {}
template <typename ArgType>
bool operator()(ArgType & arg) { return ! func(arg); }
private:
Functor & func;
};
Run Code Online (Sandbox Code Playgroud)
您可以使用如下:
bool AllSatisfy(std::vector<SomeType>& v, SomeType& valueToFind)
{
FindPredicate f(valueToFind);
return find_if(v.begin(), v.end(), Not<FindPredicate>(f)) == v.end();
}
Run Code Online (Sandbox Code Playgroud)
当然,后一种解决方案更好,因为您可以将Not struct重用于您想要的每个仿函数.
看到std库functor not1,它返回一个仿函数,它不是你给它的函子返回的逻辑.
你应该可以这样做:
bool AllSatisfy(std::vector<SomeType>& v, SomeType& valueToFind) {
return find_if(v.begin(), v.end(), not1(FindPredicate(valueToFind))) != v.end();
}
Run Code Online (Sandbox Code Playgroud)