Swiftorial Logo
Home
Swift Lessons
Tutorials
Learn More
Career
Resources

STL Functors in C++

Introduction

In C++, functors (or function objects) are objects that can be treated as though they are a function or function pointer. They're a key component of the Standard Template Library (STL) and are used extensively for scenarios where a function needs to be passed as an argument. Functors provide greater flexibility compared to function pointers because they can hold state.

What is a Functor?

A functor is any object that can be used with the function-call syntax. This is achieved by overloading the operator() in the class. Here's a basic example of a functor:

#include <iostream>

class MultiplyBy {
public:
    MultiplyBy(int factor) : factor_(factor) {}
    int operator()(int value) const {
        return value * factor_;
    }
private:
    int factor_;
};

int main() {
    MultiplyBy multiplyBy2(2);
    std::cout << "5 multiplied by 2 is " << multiplyBy2(5) << std::endl;
    return 0;
}

In this example, MultiplyBy is a functor that multiplies a given number by a factor. The operator() is overloaded to perform the multiplication.

Advantages of Functors

Functors have several advantages over regular functions:

  • Stateful: Functors can maintain state across calls, unlike simple function pointers.
  • Flexibility: Functors can be used where function pointers are expected.
  • Type Safety: Functors are type-safe and can leverage C++'s type system.

Using Functors with STL Algorithms

One of the most common uses of functors is with STL algorithms. Many algorithms in the STL, such as std::sort, accept function objects as parameters. Here's an example:

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

class Compare {
public:
    bool operator()(int a, int b) const {
        return a > b;
    }
};

int main() {
    std::vector vec = {1, 4, 3, 2, 5};
    std::sort(vec.begin(), vec.end(), Compare());

    for (int num : vec) {
        std::cout << num << " ";
    }
    return 0;
}

In this example, the Compare functor is used to sort the vector in descending order.

Built-in STL Functors

The STL provides several built-in functors for common operations. These are found in the <functional> header. Some of the common ones include:

  • std::plus: Adds two values.
  • std::minus: Subtracts the second value from the first.
  • std::multiplies: Multiplies two values.
  • std::divides: Divides the first value by the second.
  • std::greater: Returns true if the first value is greater than the second.
  • std::less: Returns true if the first value is less than the second.

Here's an example using std::greater:

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

int main() {
    std::vector vec = {1, 4, 3, 2, 5};
    std::sort(vec.begin(), vec.end(), std::greater());

    for (int num : vec) {
        std::cout << num << " ";
    }
    return 0;
}

In this example, the vector is sorted in descending order using the std::greater functor.

Custom Functors

You can create custom functors to suit your specific needs. Custom functors are particularly useful when you need to pass a parameterized operation to an STL algorithm. Here's an example of a custom functor:

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

class IsMultipleOf {
public:
    IsMultipleOf(int divisor) : divisor_(divisor) {}
    bool operator()(int value) const {
        return value % divisor_ == 0;
    }
private:
    int divisor_;
};

int main() {
    std::vector vec = {1, 4, 3, 2, 5, 10, 15};
    auto it = std::remove_if(vec.begin(), vec.end(), IsMultipleOf(2));
    vec.erase(it, vec.end());

    for (int num : vec) {
        std::cout << num << " ";
    }
    return 0;
}

In this example, the custom functor IsMultipleOf is used to remove all elements from the vector that are multiples of 2.

Conclusion

Functors are a powerful feature in C++ that allow for more flexible and reusable code. They can maintain state, be used with STL algorithms, and provide type safety. Whether using built-in STL functors or creating your own custom functors, they are an essential tool for any C++ programmer.