1. 函数对象与适配器:STL算法的灵魂组件
在C++标准模板库(STL)的设计哲学中,算法与数据结构的分离是核心思想。但当我们深入使用STL时,会发现一个关键问题:算法如何能够灵活适应各种不同的比较和操作需求?这就是函数对象(Function Objects)和适配器(Adaptors)大显身手的地方。
1.1 从函数指针到函数对象
传统C语言中,我们使用函数指针来实现回调机制,比如qsort函数:
cpp复制int compare(const void* a, const void* b) {
return (*(int*)a - *(int*)b);
}
int main() {
int arr[] = {5, 3, 7, 1, 9};
qsort(arr, 5, sizeof(int), compare);
}
这种方式的局限性非常明显:
- 类型不安全:使用void*导致类型信息丢失
- 无法内联:函数指针调用阻止编译器优化
- 不能携带状态:比较函数无法保存额外信息
C++的函数对象完美解决了这些问题:
cpp复制struct Compare {
bool operator()(int a, int b) const {
return a < b;
}
};
int main() {
std::vector<int> vec = {5, 3, 7, 1, 9};
std::sort(vec.begin(), vec.end(), Compare());
}
1.2 函数对象的本质
函数对象本质上是一个重载了operator()的类实例。这种设计带来了几个关键优势:
- 类型安全:编译器可以检查参数和返回类型
- 可内联:operator()调用可以被编译器内联优化
- 可携带状态:类可以包含成员变量保存额外信息
- 可扩展性:可以通过继承和组合构建复杂逻辑
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 标准函数对象详解
C++在
2.1 算术运算函数对象
| 函数对象 | 等效表达式 | 用途示例 |
|---|---|---|
| std::plus |
a + b | 累加、字符串拼接 |
| std::minus |
a - b | 差值计算 |
| std::multiplies |
a * b | 累乘、缩放 |
| std::divides |
a / b | 除法运算 |
| std::modulus |
a % b | 取模运算 |
| std::negate |
-a | 取负值 |
使用示例:
cpp复制std::vector<int> nums = {1, 2, 3, 4, 5};
int sum = std::accumulate(nums.begin(), nums.end(), 0, std::plus<int>());
2.2 比较运算函数对象
| 函数对象 | 等效表达式 | 用途示例 |
|---|---|---|
| std::equal_to |
a == b | 查找特定值 |
| std::not_equal_to |
a != b | 排除特定值 |
| std::less |
a < b | 默认排序 |
