Functor in Cpp : This comprehensive beginner-friendly guide explains Functor in Cpp in the simplest terms. Learn what a functor is, how it works, and why it’s useful in real-world programming. Explore different types of functors including arithmetic, relational, logical, and bitwise functors, each with clear code examples. Whether you’re a C++ beginner or brushing up on STL and object-oriented concepts, this tutorial will help you understand how function objects (functors) can make your code reusable, modular, and STL-ready.
What is a Functor in Cpp ?
In simple terms, a functor in C++ (also known as a function object) is any object that can be used like a function. It is a class or struct that overloads the operator()
, which is the function call operator.
This means you can call an object as if it were a function.
Why Use a Functor in Cpp
You might wonder: “Why use a functor when I can just use a function or a lambda?”
Here’s why functors are useful:
- ✅ They can store state or data.
- ✅ They allow custom logic to be wrapped in objects.
- ✅ They are often used in STL algorithms.
- ✅ They can offer better performance than virtual functions.
Syntax: How to Create a Functor in Cpp
Let’s understand with a simple example:
#include <iostream>
using namespace std;
// Define a functor
class Add {
public:
int operator()(int a, int b) {
return a + b;
}
};
int main() {
Add add; // Create object
cout << add(5, 3); // Call like a function
return 0;
}
Output:
8
Yes, you’re calling the object add
just like a function!
Functor vs Function vs Lambda in Cpp
Feature | Function | Functor | Lambda |
---|---|---|---|
Stores State | ❌ | ✅ | ✅ |
Reusability | ✅ | ✅ | ✅ |
OOP Friendly | ❌ | ✅ | ✅ |
Complexity | Simple | Medium | Simple to Medium |
Use in STL | ✅ | ✅ | ✅ |
Types of Functors in Cpp with Examples
In C++, the Standard Library provides ready-made functors (also called function objects) through the <functional>
header. These functors act like functions and help perform common operations like addition, comparison, logic checks, and bitwise operations.
Let’s explore the types of functors with examples:
1. Arithmetic Functors in Cpp
These functors perform basic math operations. They work just like normal arithmetic operators but in functor form.
Functor | Purpose |
---|---|
plus<T> | Adds two values |
minus<T> | Subtracts one value from another |
multiplies<T> | Multiplies two values |
divides<T> | Divides one value by another |
modulus<T> | Finds the remainder (modulo) |
negate<T> | Changes sign (negation) of value |
Example:
#include <iostream>
#include <functional>
using namespace std;
int main() {
plus<int> add;
minus<int> subtract;
multiplies<int> multiply;
divides<int> divide;
modulus<int> mod;
negate<int> negateValue;
cout << "Add: " << add(10, 5) << endl;
cout << "Subtract: " << subtract(10, 5) << endl;
cout << "Multiply: " << multiply(10, 5) << endl;
cout << "Divide: " << divide(10, 5) << endl;
cout << "Modulus: " << mod(10, 3) << endl;
cout << "Negate: " << negateValue(10) << endl;
return 0;
}
2. Relational Functors in Cpp
These are used for comparing two values, just like <
, >
, ==
, etc.
Functor | Description |
---|---|
equal_to<T> | Returns true if both values are equal |
not_equal_to<T> | Returns true if the values are not equal |
greater<T> | True if the first value is greater |
greater_equal<T> | True if the first is greater or equal |
less<T> | True if the first value is less |
less_equal<T> | True if the first is less than or equal |
Example:
#include <iostream>
#include <functional>
using namespace std;
int main() {
equal_to<int> eq;
greater<int> gt;
less<int> lt;
cout << "Equal: " << eq(10, 10) << endl; // true (1)
cout << "Greater: " << gt(10, 5) << endl; // true (1)
cout << "Less: " << lt(3, 7) << endl; // true (1)
return 0;
}
3. Logical Functors in Cpp
These work like logical operators such as &&
, ||
, and !
.
Functor | Description |
---|---|
logical_and<T> | Logical AND of two values |
logical_or<T> | Logical OR of two values |
logical_not<T> | Logical NOT of a value |
Example:
#include <iostream>
#include <functional>
using namespace std;
int main() {
logical_and<bool> land;
logical_or<bool> lor;
logical_not<bool> lnot;
cout << "AND: " << land(true, false) << endl; // false (0)
cout << "OR: " << lor(true, false) << endl; // true (1)
cout << "NOT: " << lnot(true) << endl; // false (0)
return 0;
}
4. Bitwise Functors in Cpp (Since C++17)
These perform bitwise operations similar to &
, |
, ^
.
Functor | Description |
---|---|
bit_and<T> | Bitwise AND operation |
bit_or<T> | Bitwise OR operation |
bit_xor<T> | Bitwise XOR operation |
Example (C++17 and above):
#include <iostream>
#include <functional>
using namespace std;
int main() {
bit_and<int> band;
bit_or<int> bor;
bit_xor<int> bxor;
cout << "Bitwise AND: " << band(6, 3) << endl; // 2 (110 & 011 = 010)
cout << "Bitwise OR: " << bor(6, 3) << endl; // 7 (110 | 011 = 111)
cout << "Bitwise XOR: " << bxor(6, 3) << endl; // 5 (110 ^ 011 = 101)
return 0;
}
Real Life Use Case of Functor in Cpp
Imagine you want to sort a list of employees based on salary, but in descending order. Functors help here.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Descending {
public:
bool operator()(int a, int b) {
return a > b;
}
};
int main() {
vector<int> salaries = {50000, 30000, 40000};
sort(salaries.begin(), salaries.end(), Descending());
for (int salary : salaries) {
cout << salary << " ";
}
return 0;
}
Output:
50000 40000 30000
Here, the Descending
functor helps customize the sorting logic!
When to Use Functor in Cpp?
- When you need custom behavior in algorithms
- When you want to maintain state across calls
- When working with STL containers and algorithms
- When building reusable and modular code
Can Functors Be Replaced with Lambdas?
Yes, in many cases. Lambdas are simpler and used more frequently in modern C++. However, functors are still powerful, especially in legacy systems or when stateful behavior is needed in object-oriented code.
Fun Facts about Functor in Cpp
- You can pass functors like functions.
- Functors can be templated for generic behavior.
- Many STL components like
std::greater
,std::less
, etc., are functors!
Summary
- A functor in C++ is a class/struct object that acts like a function.
- It overloads the
operator()
. - Functors can store data, customize logic, and are widely used in STL.
- They are a powerful part of object-oriented programming in C++.
FAQ: Functor in Cpp
Q1. What is the purpose of a functor in C++?
A functor allows you to use objects like functions and store state within them.
Q2. Is a functor faster than a function pointer?
Yes, in many cases. Because functors allow inline expansion by the compiler.
Q3. Can functors replace lambdas in modern C++?
Yes, but lambdas are more concise. Functors are more suitable when you need to maintain complex state.
Q4. Are functors used in STL?
Absolutely! For example, std::sort
, std::for_each
, and std::transform
can all use functors.
Interview questions on Functors in C++
Basic Level
- What is a functor in C++?
Explain that a functor is a class or struct that overloads theoperator()
allowing instances to be called like functions. - How is a functor different from a regular function or a function pointer?
Mention that functors can maintain state via member variables, unlike regular functions, and can be passed where functions are expected. - Give an example of a simple functor.
Write a small code example with a class havingoperator()
overloaded. - Why and when would you use a functor instead of a function pointer?
Talk about advantages like maintaining internal state, inline expansion by the compiler, and more flexibility.
Intermediate Level
- Can functors be used with STL algorithms? Give an example.
Explain how functors are often used with algorithms likestd::sort
,std::for_each
. - Explain how you can store state inside a functor and why that might be useful.
Discuss how member variables can be used to keep track of information across calls. - How do lambda functions relate to functors in C++?
Explain that lambdas are syntactic sugar and internally implemented as functors with overloadedoperator()
. - What are the advantages of functors over function pointers in terms of performance?
Mention inlining, avoidance of indirect function calls, and potential compiler optimizations.
Advanced Level
- Explain how to create a templated functor to work with different data types.
Show a template class withoperator()
. - Can functors be used with
std::function
? How?
Explain howstd::function
can hold functors, function pointers, lambdas, etc. - How do you implement a functor with stateful behavior that counts how many times it was called? Provide code.
Demonstrate a functor with an internal counter. - What is the difference between a stateless and a stateful functor? Give examples.
Stateful functors hold data; stateless do not. - Can you overload
operator()
with different signatures in the same functor? How does it work?
Yes, overloads are possible, and compiler picks based on call.
Sample Functor Code for Reference
#include <iostream>
// A simple functor that adds a fixed value
class AddValue {
int value;
public:
AddValue(int v) : value(v) {}
int operator()(int x) {
return x + value;
}
};
int main() {
AddValue add5(5);
std::cout << add5(10); // Output: 15
}
You can also Visit other tutorials of Embedded Prep
- Multithreading in C++
- Multithreading Interview Questions
- Multithreading in Operating System
- Multithreading in Java
- POSIX Threads pthread Beginner’s Guide in C/C++
- Speed Up Code using Multithreading
- Limitations of Multithreading
- Common Issues in Multithreading
- Multithreading Program with One Thread for Addition and One for Multiplication
- Advantage of Multithreading
- Disadvantages of Multithreading
- Applications of Multithreading: How Multithreading Makes Modern Software Faster and Smarter”
Mr. Raj Kumar is a highly experienced Technical Content Engineer with 7 years of dedicated expertise in the intricate field of embedded systems. At Embedded Prep, Raj is at the forefront of creating and curating high-quality technical content designed to educate and empower aspiring and seasoned professionals in the embedded domain.
Throughout his career, Raj has honed a unique skill set that bridges the gap between deep technical understanding and effective communication. His work encompasses a wide range of educational materials, including in-depth tutorials, practical guides, course modules, and insightful articles focused on embedded hardware and software solutions. He possesses a strong grasp of embedded architectures, microcontrollers, real-time operating systems (RTOS), firmware development, and various communication protocols relevant to the embedded industry.
Raj is adept at collaborating closely with subject matter experts, engineers, and instructional designers to ensure the accuracy, completeness, and pedagogical effectiveness of the content. His meticulous attention to detail and commitment to clarity are instrumental in transforming complex embedded concepts into easily digestible and engaging learning experiences. At Embedded Prep, he plays a crucial role in building a robust knowledge base that helps learners master the complexities of embedded technologies.
Leave a Reply