一尘不染

如何在C ++(STL)中求反函子?

algorithm

我有一些函数来查找值:

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算法。

有谁知道涉及否定谓词的解决方案?


阅读 193

收藏
2020-07-28

共1个答案

一尘不染

最好的解决方案是使用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();
}

如果您想推出自己的解决方案(恕我直言,不是最好的选择…),那么,您可以编写另一个谓词,即对第一个谓词的否定:

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 结构。

2020-07-28