CppFunctors & Predicates

Functors & Predicates

A functor (short for "function object") is simply an object of a class that overloads operator(), which makes instances of that class callable using the same syntax as an ordinary function call. Anywhere the STL expects "something callable" — a comparator for std::sort, a condition for std::count_if, a mapping for std::transform — you can pass a plain function, a lambda, or a functor, and the code that calls it doesn't need to know or care which one it received.
Why a functor instead of a plain function?
A plain function pointer cannot carry extra data with it between calls. A functor is a full object, so it can hold member variables — state that persists across calls, or configuration supplied once at construction time. Functors are also frequently easier for the compiler to inline than a call through a raw function pointer, because the concrete type (and therefore the exact operator() to call) is known at compile time rather than resolved through an indirect pointer.

A stateful counting functor and a configurable multiplier

CPP
#include <algorithm>
#include <iostream>
#include <vector>

// A functor that remembers how many times it has been invoked.
class CallCounter {
public:
    void operator()(int value) {
        ++calls;
        std::cout << "Saw: " << value << "\n";
    }

    int callCount() const { return calls; }

private:
    int calls = 0;
};

// A functor configured once at construction, then reused.
class Multiplier {
public:
    explicit Multiplier(int factor) : factor(factor) {}

    int operator()(int value) const { return value * factor; }

private:
    int factor;
};

int main() {
    std::vector<int> nums = {1, 2, 3, 4};

    CallCounter counter;
    // std::for_each returns the (possibly mutated) functor by value.
    counter = std::for_each(nums.begin(), nums.end(), counter);
    std::cout << "Total calls: " << counter.callCount() << "\n";

    Multiplier triple(3);
    std::vector<int> tripled(nums.size());
    std::transform(nums.begin(), nums.end(), tripled.begin(), triple);

    for (int n : tripled) std::cout << n << " ";
    std::cout << "\n";

    return 0;
}
Predicates
A predicate is any callable — a function, functor, or lambda — that returns a value convertible to bool. Predicates are how you plug custom logic into algorithms that need to make a yes/no decision about each element, such as filtering, counting conditionally, or defining a custom sort order.

A predicate functor used with sort and count_if

CPP
#include <algorithm>
#include <iostream>
#include <vector>

struct IsEven {
    bool operator()(int n) const { return n % 2 == 0; }
};

int main() {
    std::vector<int> nums = {5, 3, 8, 1, 9, 4};

    int evenCount = std::count_if(nums.begin(), nums.end(), IsEven());
    std::cout << "Even numbers: " << evenCount << "\n";

    // Sort so that even numbers come before odd numbers.
    std::sort(nums.begin(), nums.end(),
              [](int a, int b) { return IsEven()(a) && !IsEven()(b); });

    for (int n : nums) std::cout << n << " ";
    std::cout << "\n";

    return 0;
}

Aspect

Functor

Lambda

Reusability

Named class, reusable anywhere

Best for one-off, local use

State

Member variables, explicit and named

Captures by value/reference

Readability at call site

Just a type name

Full logic visible inline

Typical use today

Reusable, stateful, library-facing callables

Quick inline callbacks for a single algorithm call

Lambdas have largely replaced hand-written functors
In modern C++, most one-off callables passed to an algorithm are written as lambda expressions rather than dedicated functor classes — lambdas are more concise and keep the logic visible right where it's used. Functors still earn their place when you need a callable that is reused across many call sites, needs a stable name for documentation or testing, or benefits from carrying more complex state than a lambda's capture list comfortably expresses.
  • A functor is a class instance that overloads operator(), making it callable like a function.

  • Unlike a plain function pointer, a functor can carry state and is often easier to inline.

  • A predicate is any callable returning bool, used to drive conditional algorithms.

  • Modern code favors lambdas for one-off callables; functors remain useful for reusable, stateful ones.