11

I just read somebody call a class with a constructor and an operator() a predicate:

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

However, I haven't heard the word predicate being used in this context before. I would call such a thing a functor. For me, a predicate would be something from the domain of formal logic.

This raises the following questions:

  • Is this a common word for something like Foo?
  • Are both terms used interchangeably, or do they mean slightly different things?
  • Or
    • Does the return type (bool versus something else) have something to do with it?
    • What about the operator() being const?
Community
  • 1
  • 1
bitmask
  • 32,434
  • 14
  • 99
  • 159

5 Answers5

25

Functor is a term that refers to an entity that supports operator () in expressions (with zero or more parameters), i.e. something that syntactically behaves as a function. Functor is not necessarily an object of some class with overloaded operator (). Ordinary function names are functors as well. Although in some contexts you can see the term "functor" used in a more narrow and exclusive sense: just class objects, but not ordinary functions.

A predicate is a specific kind of functor: a functor that evaluates to a boolean value. It is not necessarily a value of bool type, but rather a value of any type with "boolean" semantics. The type should be implicitly convertible to bool though.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • 3
    Nice. In the general sense a functor is *any object/artifact that represents a function* by design. Whether it does so syntactically and/or with `operator()` is sugar. – Richard Sitze Aug 04 '12 at 04:31
4

The shown class is a functor that implements a predicate.

A predicate is a boolean function.

About the operator() being non-const here: it should ideally be const, yes.

Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
  • The shown class was an example. I'm wondering if every predicate is a functor. What restrictions apply, other than the return value being boolean? Would a free function that returns `bool` also be a predicate? – bitmask Aug 04 '12 at 03:37
  • Every predicate is a boolean function, at some suitable level of abstraction. Certainly predicates in Prolog are not C++ functors :-). And so yes, a free-standing function can be (used as) a predicate. Looking at the question you linked to (sorry I didn't look earlier), it's not a pure predicate, since it has a side effect. Ideally a predicate has no side effects, it just tells you whether the argument(s) fulfill some condition, typically that they have some relationship. – Cheers and hth. - Alf Aug 04 '12 at 03:41
2

A predicate is a special kind of function object. See this excellent column by Nicolai Josuttis. To quote:

A function object that returns a Boolean value is a predicate. That's what almost all tutorials, books, and manuals write about predicates of the STL. This, however, is not the whole story.

However, there is an additional requirement that is unfortunately not mentioned in any manual or in the C++ Standard: A predicate should always return the same result for the same value.

Or, in the language of C++: You should declare operator() as a constant member function (and not play games with mutable or casts). For the same reason, a copy of a predicate should have the same state as the original.

The reason is that the STL algorithms will copy function objects around, and the copying should not affect the outcome of applying the function objects.

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
    }
};
TemplateRex
  • 69,038
  • 19
  • 164
  • 304
2

As has been said, a predicate is just a user supplied directive to analyze something to a boolean state. So you can have the same two things doing the same thing...

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

private
    int count;
}

And...

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

So, what is so special about the functor? It maintains state if you want it to! That means that while these two lines of code do the same thing (assume v is a vector, with values 0 - 9)...

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

And...

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

Only with the second use case can you then call...

int calls = fn.count;

That is because for_each (as well as other STL algorithm functions) returns the functor it used at the end, so now the final state can be queried.

One other cool thing to note is that in the second case, we are using what is called an "anonymous" object.

1

From the MSDN:

Represents the method that defines a set of criteria and determines whether the specified object meets those criteria.

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

CuriousGeorge
  • 7,120
  • 6
  • 42
  • 74