Predicate和Functor之间有什么区别?

时间:2012-08-04 03:30:28

标签: c++ terminology predicate functor

我只是read有人用构造函数和operator() 谓词调用一个类:

// Example
class Foo {
  public:
    Foo(Bar);
    bool operator()(Baz);
  private:
    Bar bar;
};

但是,我之前没有听说过谓词这个词。我会称这样的东西为仿函数。对我来说,谓词将来自形式逻辑领域。

这提出了以下问题:

  • 这是Foo
  • 之类的常用词
  • 两个术语是否可以互换使用,还是意味着略有不同?
    • 返回类型(bool与其他东西相比)是否与它有关?
    • operator() const
    • 怎么样?

5 个答案:

答案 0 :(得分:22)

Functor 是一个术语,指的是在表达式中支持运算符()的实体(具有零个或多个参数),即在语法上表现为函数的东西。 Functor不一定是某个具有重载operator ()的类的对象。普通函数名称也是仿函数。虽然在某些情况下你可以看到术语“仿函数”在更狭隘和排他性的意义上使用:只是类对象,而不是普通函数。

谓词是仿函数的特定种类:一个计算为布尔值的仿函数。它不一定是bool类型的值,而是具有“boolean”语义的任何类型的值。该类型应该可以隐式转换为bool

答案 1 :(得分:3)

显示的类是一个实现谓词的仿函数。

predicate是一个布尔函数。

关于此operator()const:理想情况下应为const,是。

答案 2 :(得分:2)

谓词是一种特殊的函数对象。 Nicolai Josuttis看到这个出色的column。引用:

  

返回布尔值的函数对象是谓词。那是   几乎所有的教程,书籍和手册都是关于谓词的   STL。然而,这不是全部。

     

然而,遗憾的是还有一项额外要求   在任何手册或C ++标准中提到:谓词应该   始终为相同的值返回相同的结果。

     

或者,用C ++的语言:你应该将operator()声明为   常数成员函数(而不是使用mutable或casts玩游戏)。   出于同样的原因,谓词的副本应该具有相同的状态   作为原作。

原因是STL算法会复制函数对象,复制不应影响应用函数对象的结果。

template<typename Arg0>
struct UnaryPredicate
:
    public std::function<bool(Arg0 const&)>
{
    bool operator()(Arg0 const& a0) const
    {
        return // your code here
    }
};

template<typename Arg0, typename Arg1>
struct BinaryPredicate
:
    public std::function<bool(Arg0 const&, Arg1 const&)>
{
    bool operator()(Arg const& a0, Arg const& a1) const
    {
        return // your code here
    }
};

答案 3 :(得分:2)

如前所述,谓词只是用户提供的指令,用于分析某些布尔状态。所以你可以做同样的事情......

struct is_odd
{
    is_odd() : count(0);
    bool operartor () (int i) const { ++count; return (i % 2) == 1; }

private
    int count;
}

和...

bool isOdd(int i) { return (i % 2) == 1; }

那么,仿函数有什么特别之处呢?如果你想要它,它会保持状态!这意味着虽然这两行代码执行相同的操作(假设v是一个向量,值为0 - 9)...

for_each(v.begin(), v.end(), isOdd); //using C-style function pointer

和...

is_odd fn = for_each(v.begin(), v.end(), is_odd); //using functor

只有第二个用例才能调用...

int calls = fn.count;

这是因为for_each(以及其他STL算法函数)返回它最后使用的仿函数,所以现在可以查询最终状态。

另一个值得注意的事情是,在第二种情况下,我们正在使用所谓的“匿名”对象。

答案 4 :(得分:1)

来自MSDN:

  

表示定义一组条件并确定的方法   指定的对象是否符合这些标准。

http://msdn.microsoft.com/en-us/library/bfcke1bz.aspx