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; }