Start Coding

Topics

C++ STL Function Objects (Functors)

Function objects, also known as functors, are a powerful feature in C++ Standard Template Library (STL). They are objects that can be called like functions, providing a flexible alternative to traditional function pointers.

What are Function Objects?

Function objects are instances of classes that overload the function call operator (). This allows them to be used as if they were functions, while retaining the ability to maintain state between calls.

Syntax and Usage

To create a function object, define a class with the operator() member function:


class MyFunctor {
public:
    int operator()(int x, int y) {
        return x + y;
    }
};
    

You can then use the functor like this:


MyFunctor addObj;
int result = addObj(5, 3); // result = 8
    

Advantages of Function Objects

  • Can maintain state between function calls
  • More efficient than function pointers (can be inlined)
  • Can be used with STL Algorithms
  • Provide type safety

Predefined Function Objects in STL

The STL provides several predefined function objects in the <functional> header:

  • plus<T>
  • minus<T>
  • multiplies<T>
  • divides<T>
  • modulus<T>
  • negate<T>

Example: Using Predefined Function Objects


#include <iostream>
#include <functional>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    int sum = 0;

    std::for_each(numbers.begin(), numbers.end(), [&sum](int n) {
        sum += n;
    });

    std::cout << "Sum: " << sum << std::endl;

    return 0;
}
    

Custom Function Objects

You can create custom function objects to encapsulate complex operations or maintain state. Here's an example of a custom functor that counts how many times it's been called:


class Counter {
private:
    int count = 0;
public:
    int operator()() {
        return ++count;
    }
};

int main() {
    Counter c;
    std::cout << c() << std::endl; // Outputs: 1
    std::cout << c() << std::endl; // Outputs: 2
    std::cout << c() << std::endl; // Outputs: 3
    return 0;
}
    

Function Objects vs Lambda Expressions

While Lambda Expressions provide a concise way to create inline function objects, traditional functors still have their place:

  • Functors can have multiple overloaded operator() functions
  • They can be more readable for complex operations
  • Functors can be easily reused across different parts of your code

Best Practices

  • Use function objects when you need to maintain state between calls
  • Consider using predefined STL function objects for common operations
  • Combine function objects with STL Algorithms for powerful, reusable code
  • Use Lambda Expressions for simple, one-off functors

Function objects are a cornerstone of generic programming in C++. They provide a flexible and efficient way to customize the behavior of STL algorithms and containers. By mastering functors, you'll be able to write more expressive and performant C++ code.