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