C++ Functors

A C++ functor (function object) is a class or struct object that can be called like a function.

It overloads the function-call operator () and allows us to use an object like a function.


Create a Functor in C++

We can create a functor in C++ as:

class Greet {
  public:
    void operator()() {
      // function body
    }
};

Here, we are overloading the function call operator (). This allows us to call the class object as if it were a function as shown below:

// create an instance of Greet
Greet greet;

// call the object as a function
greet(); 

Note: Remember to set public access specifier while overloading the () operator for the class, since by default the members of a class are private.


Example 1: C++ Functor

#include <iostream>
using namespace std;

class Greet { public: // overload function call/parentheses operator void operator()() { cout << "Hello World!"; } };
int main() { // create an object of Greet class Greet greet;
// call the object as a function greet();
return 0; }

Output

Hello World!

In the above example, we have created a simple program that prints Hello World! using C++ functors.

In order to create a functor, we first have to create a class whose object we can call like a function. So, we have created a class named Greet.

Inside the Greet class

Here, we have overloaded the function call operator () using:

class Greet {

public:
  // overload function call operator
  void operator()() {
    cout << "Hello World!";
  }
};

Here, our overloaded function simply prints Hello World!.

Inside the main() Function

Here, we have created an object called greet from the Greet class.

Greet greet;

Now, we call the greet object using the () operator:

// displays "Hello World!"
greet() 

Alternatively, we can call greet using the following code:

// displays "Hello World!"
greet.operator()();

C++ Functor With Return Type and Parameters

We can also define a functor that accepts parameters and returns a value. For example,

#include <iostream>
using namespace std;

class Add {

  public:
// overload function call operator // accept two integer arguments // return their sum int operator() (int a, int b) { return a + b; }
}; int main() { // create an object of Add class Add add;
// call the add object int sum = add(100, 78);
cout << "100 + 78 = " << sum; return 0; }

Output

100 + 78 = 178

In the above example, we have used a functor with an integer return type and two integer parameters to find their sum.

class Add {
  public:
    int operator()(int a, int b) {
      return a + b;
    }
};

Inside main(), we have created the add object from the Add class.

Then, we have called the add object with parameters 100 and 78. The return value from the functor is assigned to the sum variable.

// returns 178
int sum = add(100, 78);

Example 2: C++ Functor With a Member Variable

#include<iostream>
using namespace std;

class Add_To_Sum {

  private:
int initial_sum;
public: // constructor to initialize member variable Add_To_Sum(int sum) { initial_sum = sum; }
// overload function call operator int operator()(int num) { return initial_sum + num; }
}; int main() { // create object of Add_To_Sum class // initialize member variable of object with value 100 Add_To_Sum add = Add_To_Sum(100);
// call the add object with 78 as argument int final_sum = add(78);
cout << "100 + 78 = " << final_sum; return 0; }

Output

100 + 78 = 178

In the above example, the Add_To_Sum class has a member variable initial_sum. We have initialized this variable using a constructor:

// constructor to initialize member variable
Add_To_Sum(int sum) {
  initial_sum = sum;
}

Then, we have overloaded the function call operator that:

  • adds its parameter num to the initial_sum variable
  • then returns the result.
int operator()(int num) {
  return initial_sum + num;
}

In main(), we have initialized the initial_sum variable of the add object to 100 using the parameterized constructor:

// initialize initial_sum variable to 100
Add_To_Sum add = Add_To_Sum(100);

Finally, we have called the functor and passed 78 as an argument.

// returns sum of 100 and 78 i.e 178
int final_sum = add_to_100(78); 

C++ Predefined Functors

We can use predefined functors provided by the standard library by including the functional header file:

#include <functional>

C++ provides the following library functors for arithmetic, relational, and logical operations.

1. Arithmetic Functors

Functors Description
plus returns the sum of two parameters
minus returns the difference of two parameters
multiplies returns the product of two parameters
divides returns the result after dividing two parameters
modulus returns the remainder after dividing two parameters
negate returns the negated value of a parameter

2. Relational Functors

Functors Description
equal_to returns true if the two parameters are equal
not_equal_to returns true if the two parameters are not equal
greater returns true if the first parameter is greater than the second
greater_equal returns true if the first parameter is greater than or equal to the second
less returns true if the first parameter is less than the second
less_equal returns true if the first parameter is less than or equal to the second

3. Logical Functors

Functors Description
logical_and returns the result of Logical AND operation of two booleans
logical_or returns the result of Logical OR operation of two booleans
logical_not returns the result of Logical NOT operation of a boolean

4. Bitwise Functors

Functors Description
bit_and returns the result of Bitwise AND operation of two parameters
bit_or returns the result of Bitwise OR operation of two parameters
bit_xor returns the result of Bitwise XOR operation of two parameters

Example 3: C++ Predefined Functor with STL

Usually, functors are used with C++ STL as arguments to STL algorithms like sort, count_if, all_of, etc.

In this example, we will look at a predefined C++ functor greater<T>(), where T is the type of the functor parameter with the STL algorithm sort.

#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std; int main() { // initialize vector of int vector<int> nums = {1, 20, 3, 89, 2};
// sort the vector in descending order sort(nums.begin(), nums.end(), greater<int>());
for(auto num: nums) { cout << num << ", "; } return 0; }

Output

89, 20, 3, 2, 1

In the above example, we have used a predefined functor to sort a vector of integers (called nums) in descending order.

By default, the sort() function sorts the elements in ascending order.

In order ro make it sort in descending order, we have used the predefined functor greater<T>.

sort(nums.begin(), nums.end(), greater<int>());

Notice that we have used the code greater<int>(). This is because nums is an integer vector, so we use int in place of T.

Finally, we print the sorted vector using a ranged for loop.


Frequently Asked Questions

How to create a functor using C++ struct?
#include <iostream>
using namespace std;

struct Greet { // overload function call/parentheses operator void operator()() { cout << "Hello World!"; } };
int main() { // create a variable of Greet struct Greet greet; // call the struct variable as a function greet(); return 0; }

Output

Hello World!

In the above example, we have created a struct named Greet and overloaded the () operator to print Hello World!.

In main(), we have created a variable of Greet and called the functor using the () operator:

Greet greet;

// Output: Hello World!
greet();
How to use custom functors with STL algorithms?
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

class Even_Counter {

  public:
// overload function call operator // returns true if the n is even bool operator()(int n) { return n % 2 == 0; }
}; int main() { // initialize vector of integers vector<int> nums = {1, 2, 3, 4, 5, 8, 10, 12};
// create an object of Even_Counter Even_Counter even_counter; // count the number of even numbers in the vector int even_count = count_if(nums.begin(), nums.end(), even_counter);
cout << "There are " << even_count << " even numbers."; return 0; }

Output

There are 5 even numbers.

In the above example, we have used a custom functor with the STL algorithm count_if to count the total even numbers in a vector nums.

We have created a class named Even_Counter and overloaded the function call operator to return true if the number is even.

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

In main(), we have created an integer vector named nums and an Even_Counter object named even_counter.

Then, we use the count_if algorithm to count the number of even integers in nums:

int even_count = count_if(nums.begin(), nums.end(), even_counter);

Notice that we have passed the even_counter functor as the third argument to count_if.

The even_counter functor takes the current vector element as its argument n and returns true if n is even.

How can we create generic functors?

We can create a generic functor by overloading the function call operator with type parameters. For this, we need to use class templates.

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

template<typename T> class Greater_Than { public: // returns true if left is greater than right bool operator()(const T &left, const T &right) { return left > right; } };
int main() { // initialize vector of int vector<int> int_nums = {1, 20, 3, 89, 2}; // sort the vector in descending order
sort(int_nums.begin(), int_nums.end(), Greater_Than<int>());
for(auto num: int_nums) { cout << num << ", "; } return 0; }

Output

89, 20, 3, 2, 1

In the above example, we have implemented a functor Greater_Than<T> which acts similar to C++ predefined function greater<int>.

By default, the STL sort() function sorts the elements in ascending order.

Inside Greater_Than Class:

template<typename T>
class Greater_Than {
  public:
    bool operator()(const T &left,const T &right) {
      return left > right;
    }
};

Inside main() Function:

We have initialized an integer vector int_nums. We then sort the vector using the STL sort() function.

// sort the vector in descending order
sort(int_nums.begin(), int_nums.end(), Greater_Than<int>());

Notice that we have not created an object of Greater_Than class but passed Greater_Than<int>() as the third argument which creates a function object.

This is equivalent to:

Greater_Than<int> greater_than;

// sort the vector in descending order
sort(int_nums.begin(), int_nums.end(), greater_than);
Did you find this article helpful?