24、函数对象与谓词
大约 3 分钟C++C++基础编程程序厨
函数对象(Function Object)在C++
中比较常用,它允许将函数作为对象来处理,提高代码的灵活性和可复用性。
谓词(Predicate)是一种特殊的函数对象,用于返回布尔值。
本文会介绍相关概念。
函数对象
函数对象是一个类对象,它重载了函数调用运算符operator()
,使得对象可以像函数一样被调用。函数对象可以存储状态,并且可以作为参数传递给算法。它通常通过定义一个类并重载operator()
来实现。
代码示例:
#include <iostream>
// 定义一个函数对象类
class Add {
public:
int operator()(int a, int b) const {
return a + b;
}
};
int main() {
Add add; // 创建函数对象
int result = add(3, 4); // 调用函数对象
std::cout << "Result: " << result << std::endl; // 输出:7
return 0;
}
谓词
谓词是一种返回布尔值的函数或函数对象,它通常用于条件判断。谓词可以分为一元谓词(接受一个参数)和二元谓词(接受两个参数)。
谓词常用于STL算法中,比如std::find_if
、std::remove_if
等。
一元谓词:
#include <iostream>
#include <vector>
#include <algorithm>
// 定义一元谓词
class IsEven {
public:
bool operator()(int num) const {
return num % 2 == 0;
}
};
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// 使用std::find_if查找第一个偶数
std::vector<int>::iterator it = std::find_if(vec.begin(), vec.end(), IsEven());
if (it != vec.end()) {
std::cout << "First even number: " << *it << std::endl; // 输出:2
} else {
std::cout << "No even number found." << std::endl;
}
return 0;
}
二元谓词:
#include <iostream>
#include <vector>
#include <algorithm>
// 定义二元谓词
class Compare {
public:
bool operator()(int a, int b) const {
return a > b; // 降序排序
}
};
int main() {
std::vector<int> vec = {5, 3, 1, 4, 2};
// 使用std::sort和二元谓词进行降序排序
std::sort(vec.begin(), vec.end(), Compare());
// 输出排序后的vector
for (int num : vec) {
std::cout << num << " "; // 输出:5 4 3 2 1
}
std::cout << std::endl;
return 0;
}
内置函数对象与适配器
标准库中的函数对象
STL提供了许多内置的函数对象,定义在<functional>
头文件中。常见的函数对象有:
- 算术运算:
std::plus
、std::minus
、std::multiplies
、std::divides
、std::modulus
、std::negate
- 关系运算:
std::equal_to
、std::not_equal_to
、std::greater
、std::less
、std::greater_equal
、std::less_equal
- 逻辑运算:
std::logical_and
、std::logical_or
、std::logical_not
示例代码,greater
:
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
int main() {
std::vector<int> vec = {5, 3, 1, 4, 2};
// 使用std::sort和std::greater进行降序排序
std::sort(vec.begin(), vec.end(), std::greater<int>());
// 输出排序后的vector
for (int num : vec) {
std::cout << num << " "; // 输出:5 4 3 2 1
}
std::cout << std::endl;
return 0;
}
函数对象适配器
函数对象适配器用于修改或组合现有的函数对象,常见的适配器有std::bind
、std::bind1st
(C++17已移除)、std::bind2nd
(C++17已移除)
std::bind
示例代码:
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
int main() {
std::vector<int> vec = {1, 2, 3, 4, 5};
// 使用std::bind绑定std::greater的第二个参数为3
auto greaterThan3 = std::bind(std::greater<int>(), std::placeholders::_1, 3);
// 使用std::find_if查找第一个大于3的元素
std::vector<int>::iterator it = std::find_if(vec.begin(), vec.end(), greaterThan3);
if (it != vec.end()) {
std::cout << "First number greater than 3: " << *it << std::endl; // 输出:4
} else {
std::cout << "No number greater than 3 found." << std::endl;
}
return 0;
}
练习
- 定义一个函数对象类
Multiply
,用于计算两个数的乘积,并使用std::transform
将其应用于一个std::vector
。 - 使用
std::bind
和std::less
实现一个函数对象,用于判断一个数是否小于10,并使用std::count_if
统计std::vector
中小于10的元素个数。
