SoFunction
Updated on 2025-04-14

The conceptual advantages and usage of C++ functors

Preface

In C++, functors (Functors) refer to overloadingoperator()Objects of classes or structures, which behave like ordinary functions, can be called like functions. Fiction functions are widely used in STL algorithms, callback mechanisms, function adapters and other scenarios. This article will explore in-depth the concept, advantages and usage of functors, and analyze them in detail based on specific examples.

1. Why do I need a mimicking function?

In C++, we can use normal functions orstd::function(Introduced in C++11) to define callable objects, but functors have the following advantages in comparison:

  • State storage: Normal functions cannot store state, while functors can maintain states inside objects, such as counters, thresholds, etc.
  • Performance optimization: Since functors are instances of classes, inline optimization can reduce the overhead of function calls.
  • Compatible with STL: STL containers and algorithms use functors widely, such asstd::sort()Fiction functions are acceptable as custom sorting rules.

2. Basic usage of functors

To define a functor, you need to overload it in a class or structureoperator(), the examples are as follows:

#include <iostream>
// Define functor classesstruct Add {
    int operator()(int a, int b) {
        return a + b;
    }
};
int main() {
    Add add; // Create functor object    std::cout << "3 + 5 = " << add(3, 5) << std::endl; // Call like a function    return 0;
}

Analysis

  • operator()makeAddObjectaddBecome a callable object, similar to a normal functionadd(3, 5)
  • operator()The parameters can be accepted and the calculation results can be returned.

3. Simulation functions with states

A functor can store state so that it holds data between multiple calls. For example, create a functor that calculates the number of calls:

#include <iostream>
class Counter {
private:
    int count;
public:
    Counter() : count(0) {}  // Initialize counter to 0    int operator()(int value) {
        count++;
        return count * value; // Use count to affect the calculation results    }
    int getCount() const { return count; }
};
int main() {
    Counter counter;
    std::cout << counter(10) << std::endl; // The first call    std::cout << counter(10) << std::endl; // The second call    std::cout << "Number of calls:" << () << std::endl;
    return 0;
}

Analysis

  • countStore state as member variable, each calloperator()Will increasecount
  • This is very useful in scenarios such as STL algorithms, callback mechanisms, etc.

4. Simulation functions in STL algorithm

STL algorithms usually require comparison, transformation, filtering and other rules, and custom functors are particularly useful at this time. For example, custom sorting:

#include <iostream>
#include <vector>
#include <algorithm>
// Custom comparison rules (descending order)struct Compare {
    bool operator()(int a, int b) {
        return a > b; // Sort in descending order    }
};
int main() {
    std::vector<int> vec = {5, 2, 8, 1, 3};
    std::sort((), (), Compare()); // Pass functor object    for (int num : vec) {
        std::cout << num << " ";
    }
    return 0;
}

Analysis

  • std::sort()The default is ascending order, we customize itCompareAs a descending order comparison rule.
  • std::sort((), (), Compare());PassedCompareTemporary objects of type are used as sorting criteria.

5. Standard imitation functions provided by STL

C++ STL provides some standard functors, mainly in<functional>In the header file, for example:

  • Arithmetic operation functor:std::plus<T>std::minus<T>std::multiplies<T>std::divides<T>wait.
  • Relational operation functor:std::greater<T>std::less<T>std::equal_to<T>wait.
  • Logical operation functor:std::logical_and<T>std::logical_or<T>wait.

Example: Usestd::greater<>Sort in descending order:

#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include <functional> // Includes standard imitation functionsint main() {
    std::vector&lt;int&gt; vec = {5, 2, 8, 1, 3};
    std::sort((), (), std::greater&lt;int&gt;()); // Sort by descending order using standard functors    for (int num : vec) {
        std::cout &lt;&lt; num &lt;&lt; " ";
    }
    return 0;
}

Analysis

std::greater<int>()Asstd::sortComparison function with what we wrote ourselvesCompareSimilar effects.

6. Lambda replaces functors (C++11)

C++11 introduces Lambda expressions to make the code more concise. Lambda can be used instead of many functor usage scenarios. For example:

#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
int main() {
    std::vector&lt;int&gt; vec = {5, 2, 8, 1, 3};
    // Sort in descending order using Lambda    std::sort((), (), [](int a, int b) { return a &gt; b; });
    for (int num : vec) {
        std::cout &lt;&lt; num &lt;&lt; " ";
    }
    return 0;
}

Why use Lambda?

  • Reduce code volume: no need to define separatelystructAs a functor class.
  • Improve readability: Lambda directlystd::sort()Define logic at the location, and the code is more intuitive.

Although Lambda is more concise, functors are still a good choice when they need to store state, reuse code, and use across multiple places.

7. Summary

characteristic Normal functions Lambda Simulation functions
Whether the state can be stored ❌ No ⚠️ Closure only ✅ Yes
Is it reusable ✅ Yes ❌ No (local scope only) ✅ Yes
Performance optimization ⚠️ It may not be possible to inline ✅ Inline Optimization ✅ Inline Optimization
Applicable scenarios General calculation Simple one-time logic STL, callback, complex logic

When to choose a mimetic function

  • Requires storage status (such as a counter).
  • Reuse is required (multiple places use the same logic).
  • Requires STL compatibility (e.g.std::sort())。
  • Efficient optimization (inline) is required.

Fiction functions are an important concept in the C++ language. They enable objects to be called like functions and play an important role in STL algorithms, callbacks, state storage and other scenarios. Although Lambda introduced in C++11 makes the code more concise, functors are still irreplaceable in certain specific scenarios such as STL and state hold.

The above is the concept advantages and detailed content of C++ functors. For more information about C++ functors, please pay attention to my other related articles!