Open In App

When to Use a Functor Instead of a Function in C++?

Last Updated : 11 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In C++, both functors and functions can be used to encapsulate behavior and provide callable objects. Still, there are specific scenarios where using a functor is more advantageous than a regular function. In this article, we will learn when to use a functor instead of a function in C++.

When to Prefer Functors Instead of Function?

In C++, prefer to use a functor instead of a function in the following cases:

1. Stateful Computations

If we need to maintain state information between calls, functors are a good choice. Unlike regular functions, functors can store state information in member variables and use it across multiple calls.

Example:

C++




// C++ program to use functors for Stateful Computations 
#include <iostream>
using namespace std;
  
// Struct representing a counter with a count variable
struct Counter {
    int count = 0; // Initial count is 0
  
    // Overloaded function call operator to increment count
    // and print it
    void operator()()
    {
        cout << "Count: " << count++ << endl;
    }
};
  
int main()
{
    Counter counter; // Creating an instance of Counter
    // Invoking the counter twice
    counter(); // Count: 0
    counter(); // Count: 1
  
    return 0;
}


Output

Count: 0
Count: 1

2. Parameterized Behavior

Functors can be parameterized when they are constructed. This allows you to create a functor with specific behavior that can be used later.

Example:

C++




// C++ program to use parametrized functors
  
#include <iostream>
using namespace std;
  
// Struct representing a multiplier with a factor variable
struct Multiplier {
    int factor; // Factor to multiply by
  
    // Constructor to initialize the factor
    Multiplier(int factor)
        : factor(factor)
    {
    }
  
    // Overloaded function call operator to perform
    // multiplication
    int operator()(int input) { return input * factor; }
};
  
int main()
{
    Multiplier multiplyByThree(
        3); // Creating an instance of Multiplier with
            // factor 3
  
    // Using the multiplier to multiply 5 by 3
    cout << "3 * 5 = " << multiplyByThree(5) << endl;
  
    return 0;
}


Output

3 * 5 = 15

3. Overloading Function Call Operator

Functors allow overloading of the function call operator that means we can have different versions of the operator() function that take different numbers or types of parameters, providing more flexibility.

Example:

C++




// C++ program to use Functors to overload the function call
// operator
  
#include <iostream>
#include <string>
using namespace std;
  
// Struct representing an overloaded functor
struct OverloadedFunctor {
    // Overloaded function call operator for integers
    void operator()(int x)
    {
        cout << "Integer: " << x << endl;
    }
  
    // Overloaded function call operator for strings
    void operator()(const string& x)
    {
        cout << "String: " << x << endl;
    }
};
  
int main()
{
    // Creating an instance of the overloaded functor
    OverloadedFunctor functor;
  
    // Using the functor to print an integer and a string
    functor(42);
    functor("Hello, Functor!");
  
    return 0;
}


Output

Integer: 42
String: Hello, Functor!

4. Use with STL Algorithms

Many STL algorithms like std::sortstd::transform, etc., accept functors as arguments so, functors can be used to customize the behavior of these algorithms.

Example:

C++




// C++ program to use functor with STL algorithm
  
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
  
// Functor for multiplication by 2
struct Multiply {
    int operator()(int x) const { return x * 2; }
};
  
int main()
{
    vector<int> vec = { 1, 2, 3, 4, 5 };
    vector<int> result(vec.size());
  
    // Using std::transform with Multiply functor to
    // multiply each element by 2
    transform(vec.begin(), vec.end(), result.begin(),
              Multiply());
  
    // Printing the result
    for (int i : result) {
        cout << i << " "; // Output: 2 4 6 8 10
    }
    cout << endl;
  
    return 0;
}


Output

2 4 6 8 10 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads