C++ STL 仿函数(Functors)详解

仿函数(函数对象)是STL中强大的抽象工具,允许将函数作为参数传递,同时保持状态和类型安全

什么是仿函数?

仿函数(也称为函数对象)是重载了函数调用操作符operator()的类对象。它们可以像普通函数一样被调用,但具有状态,可以存储和传递数据。

基本仿函数示例
#include <iostream>

// 自定义仿函数 - 加法器
class Adder {
public:
    Adder(int num) : num_(num) {}
    
    int operator()(int x) const {
        return x + num_;
    }
    
private:
    int num_;
};

int main() {
    Adder add5(5);
    std::cout << "10 + 5 = " << add5(10) << std::endl; // 输出 15
    
    Adder add10(10);
    std::cout << "10 + 10 = " << add10(10) << std::endl; // 输出 20
    
    return 0;
}

仿函数的优势

仿函数分类

STL提供了内置的仿函数,同时允许用户自定义仿函数

算术仿函数

plus, minus, multiplies, divides, modulus, negate

std::plus<int> add;
int result = add(10, 20); // 30

关系仿函数

equal_to, not_equal_to, greater, greater_equal, less, less_equal

std::greater<int> gt;
bool result = gt(10, 5); // true

逻辑仿函数

logical_and, logical_or, logical_not

std::logical_and<bool> and_op;
bool result = and_op(true, false); // false

自定义仿函数

开发者根据需求定义的函数对象

class Square {
public:
    int operator()(int x) const {
        return x * x;
    }
};

仿函数使用示例

仿函数在STL算法中的应用

使用仿函数进行排序和转换
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional> // 包含STL仿函数

// 自定义仿函数 - 平方
class Square {
public:
    int operator()(int x) const {
        return x * x;
    }
};

int main() {
    std::vector<int> nums = {1, 2, 3, 4, 5};
    std::vector<int> squares(nums.size());
    
    // 使用内置仿函数进行降序排序
    std::sort(nums.begin(), nums.end(), std::greater<int>());
    std::cout << "降序排序: ";
    for (int n : nums) std::cout << n << " ";
    
    // 使用自定义仿函数进行转换
    std::transform(nums.begin(), nums.end(), squares.begin(), Square());
    std::cout << "\n平方值: ";
    for (int n : squares) std::cout << n << " ";
    
    // 使用lambda表达式作为仿函数
    int threshold = 10;
    auto count = std::count_if(squares.begin(), squares.end(), 
        [threshold](int x) { return x > threshold; });
    std::cout << "\n大于" << threshold << "的值数量: " << count;
    
    return 0;
}

输出结果

降序排序: 5 4 3 2 1 
平方值: 25 16 9 4 1 
大于10的值数量: 2

最佳实践