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
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,
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
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.
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
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();
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.
We can create a generic functor by overloading the function call operator with type parameters. For this, we need to use class templates.
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);