Search code examples
c++operator-overloadingpredicate

Overload of parentheses operator - passing an argument to predicate functions


This example of operator() overload is clear and straightforward:

struct add_x {
  add_x(int val) : x(val) {}  // Constructor
  int operator()(int y) const { return x + y; }
private:
  int x;
};
add_x add42(42);
int i = add42(8);
assert(i == 50);

add_x add42(42) defines a functor with 42 set as private member, next int i = add42(8) calls this functor with 8 as argument. Next operator() adds 42 and 8 and returns 50. Just great.

However, how on earth does this example work:

 std::vector<int> v(10, 2);
// some code here
struct DivisibleBy
    {
        const int d;
        DivisibleBy(int n) : d(n) {}
        bool operator()(int n) const { return n % d == 0; }
    };
 
    if (std::any_of(v.cbegin(), v.cend(), DivisibleBy(7)))
        std::cout << "At least one number is divisible by 7\n";

DivisibleBy(7) creates an instance of DivisibleBy with 7 set as struct member. How does any_of() realize that it has to pass vector values to DivisibleBy used here as a predicate function? This definitely works:

    if (std::any_of(v.cbegin(), v.cend(), [](int i) {
        DivisibleBy db7 = DivisibleBy(7);
        return db7(i);} ))
        std::cout << "At least one number is divisible by 7\n";

I define an inline predicate function with explicit int i argument which receives values defined by iterators. However, the former example (any_of(v.cbegin(), v.cend(), DivisibleBy(7))) has no argument to catch values from iteration. I assume this

bool operator()(int n) const

is the place where magic happens, but cannot find any explicit reference how exactly does it work?


Solution

  • The expression DivisibleBy(7) creates a temporary object, which is passed to std::any_of. This objects function-call operator is called as usual.

    It's similar to:

    DivisibleBy by7(7);
    if (std::any_of(v.cbegin(), v.cend(), by7))
        std::cout << "At least one number is divisible by 7\n";