functional
<functional> 提供函数对象(仿函数)、函数适配器和常用谓词工具,是 STL 算法可配置性的关键部分。
在 C++98 时代,还没有 lambda,很多“把行为当参数传递”的写法依赖 <functional>。
头文件与核心概念
#include <functional>
常见概念:
- 函数对象:实现了
operator()的对象。 - 谓词:返回
bool的函数对象,常用于算法筛选。 - 适配器:把已有函数对象做“绑定、组合、取反”等处理。
常见函数对象
<functional> 内置了大量基本运算函数对象:
| 类型 | 作用 |
|---|---|
std::plus<T> | 加法 |
std::minus<T> | 减法 |
std::multiplies<T> | 乘法 |
std::divides<T> | 除法 |
std::equal_to<T> | 相等比较 |
std::less<T> | 小于比较 |
std::greater<T> | 大于比较 |
示例:
#include <functional>
#include <iostream>
int main() {
std::plus<int> add;
std::less<int> less;
std::cout << add(3, 4) << '\n';
std::cout << (less(2, 5) ? "true" : "false") << '\n';
return 0;
}
与算法配合
#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>
int main() {
std::vector<int> nums;
nums.push_back(1);
nums.push_back(3);
nums.push_back(2);
std::sort(nums.begin(), nums.end(), std::greater<int>());
for (std::vector<int>::iterator it = nums.begin(); it != nums.end(); ++it) {
std::cout << *it << ' ';
}
std::cout << '\n';
return 0;
}
bind1st / bind2nd(C++98 常见)
在 C++98 里,可以用 bind1st、bind2nd 预绑定参数:
#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>
int main() {
std::vector<int> nums;
nums.push_back(1);
nums.push_back(2);
nums.push_back(3);
nums.push_back(4);
int c = std::count_if(nums.begin(), nums.end(), std::bind2nd(std::greater<int>(), 2));
std::cout << c << '\n'; // 统计 > 2 的个数
return 0;
}
not1 / not2
可对谓词结果取反:
#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>
int main() {
std::vector<int> nums;
nums.push_back(0);
nums.push_back(1);
nums.push_back(0);
int zeros = std::count_if(nums.begin(), nums.end(), std::not1(std::bind2nd(std::not_equal_to<int>(), 0)));
std::cout << zeros << '\n';
return 0;
}
使用注意
- C++98 中
<functional>很常用,C++11 以后许多场景会改用 lambda。 bind1st/bind2nd表达能力有限,复杂逻辑可自定义函数对象。- 谓词要满足算法语义要求,避免副作用过重。