C++ 中的仿函数(Functor)是通过重载函数调用运算符 operator() 的类对象,它可以像普通函数一样被调用。仿函数的优点是状态可以保存在对象中,允许灵活配置行为,常用于标准模板库(STL)中的算法(如 sort、for_each)中,替代函数指针以实现更高效、类型安全的回调机制,也适用于实现策略模式、延迟执行等功能。

1、仿函数简介 

仿函数(functor) 是一个定义了 operator()操作符的类或结构体对象。这样定义后,实例化该类的对象就可以像函数一样被调用。
它的本质是一个可以像函数一样使用的对象,因此也称为函数对象(function object)

#include<iostream>
using namespace std;

class Adder {
public:
    int operator()(int a, int b) const {
        return a + b;
    }
};

int main() {
    Adder add;
    std::cout << "3 + 5 = " << add(3, 5) << std::endl;  // 像函数一样调用
    return 0;
}

2、仿函数的优势

与普通函数相比,仿函数可以保存状态(成员变量),实现比函数指针更灵活的行为。可用于泛型编程C++ STL 算法如 std::sort 支持仿函数作为自定义比较器。编译器可以内联仿函数的调用,避免函数指针的调用开销。

1)用作排序比较器

#include<iostream>
using namespace std;
#include <algorithm>
#include <vector>
#include <iostream>

struct Descending {
    bool operator()(int a, int b) const {
        return a > b;
    }
};

int main() {
    std::vector<int> nums = {3, 1, 4, 1, 5};
    std::sort(nums.begin(), nums.end(), Descending());

    for (int n : nums)
        std::cout << n << " ";  // 输出:5 4 3 1 1
}

2)带状态的仿函数

#include<iostream>
using namespace std;

class Multiplier {
    int factor;
public:
    Multiplier(int f) : factor(f) {}
    int operator()(int x) const { return x * factor; }
};

int main() {
    Multiplier times3(3);
    std::cout << times3(10) << std::endl;  // 输出 30
}

3、与 Lambda 表达式的比较

C++11 引入了 Lambda 表达式,它也可以生成匿名的函数对象。其本质与仿函数一致,但写法更简洁。

#include<iostream>
using namespace std;


int main() {
    // 定义一个 Lambda 表达式,用于两个整数相加
    auto add = [](int a, int b) { return a + b; };

    // 调用 Lambda 表达式
    int result = add(1, 2);

    // 输出结果
    std::cout << "1 + 2 = " << result << std::endl;

    return 0;
}