函数对象(Function Objects),也称为仿函数(Functors),是C++ STL中的重要概念。它们是重载了operator()
的类或结构体的对象,可以像函数一样被调用,同时具备对象的特性。
还有一个概念,只要可以与小括号进行结合展示出函数含义都可以称为可调用对象。
可调用对象包含了:
函数对象
函数指针
函数名
lambda表达式(可视为一个匿名的函数对象,可以直接在定义后调用,也可以给function函数对象赋值)
很多资料中模糊了函数对象和可调用对象的概念说明。下图出自C++之父的书《C++程序设计语言-第4卷》
还有一个更大范围的概念:可调用实体,它在可调用对象的基础上还增加了成员函数、成员函数指针、指向数据成员的指针(这三者的共同特点是也可以调用,但不能仅凭自己完成调用)。
xxxxxxxxxx
281
2
3
4
5
6int main() {
7 std::vector<int> vec1 = {1, 2, 3, 4, 5};
8 std::vector<int> vec2 = {10, 20, 30, 40, 50};
9 std::vector<int> result(5);
10
11 // 使用std::plus进行加法运算
12 std::transform(vec1.begin(), vec1.end(), vec2.begin(),
13 result.begin(), std::plus<int>());
14
15 for (int val : result) {
16 std::cout << val << " "; // 输出: 11 22 33 44 55
17 }
18 std::cout << std::endl;
19
20 // 其他算术函数对象
21 std::cout << std::minus<int>{}(10, 3) << std::endl; // 7
22 std::cout << std::multiplies<int>{}(4, 5) << std::endl; // 20
23 std::cout << std::divides<int>{}(20, 4) << std::endl; // 5
24 std::cout << std::modulus<int>{}(17, 5) << std::endl; // 2
25 std::cout << std::negate<int>{}(42) << std::endl; // -42
26
27 return 0;
28}
xxxxxxxxxx
251
2
3
4
5
6int main() {
7 std::vector<int> numbers = {5, 2, 8, 1, 9, 3};
8
9 // 使用std::greater进行降序排序
10 std::sort(numbers.begin(), numbers.end(), std::greater<int>());
11
12 for (int num : numbers) {
13 std::cout << num << " "; // 输出: 9 8 5 3 2 1
14 }
15 std::cout << std::endl;
16
17 // 其他比较函数对象
18 std::cout << std::equal_to<int>{}(5, 5) << std::endl; // 1 (true)
19 std::cout << std::not_equal_to<int>{}(5, 3) << std::endl; // 1 (true)
20 std::cout << std::less<int>{}(3, 5) << std::endl; // 1 (true)
21 std::cout << std::less_equal<int>{}(5, 5) << std::endl; // 1 (true)
22 std::cout << std::greater_equal<int>{}(5, 3) << std::endl; // 1 (true)
23
24 return 0;
25}
xxxxxxxxxx
391
2
3
4
5
6int main() {
7 std::vector<bool> vec1 = {true, false, true, false};
8 std::vector<bool> vec2 = {true, true, false, false};
9 std::vector<bool> result(4);
10
11 // 逻辑与运算
12 std::transform(vec1.begin(), vec1.end(), vec2.begin(),
13 result.begin(), std::logical_and<bool>());
14
15 for (bool val : result) {
16 std::cout << val << " "; // 输出: 1 0 0 0
17 }
18 std::cout << std::endl;
19
20 // 逻辑或运算
21 std::transform(vec1.begin(), vec1.end(), vec2.begin(),
22 result.begin(), std::logical_or<bool>());
23
24 for (bool val : result) {
25 std::cout << val << " "; // 输出: 1 1 1 0
26 }
27 std::cout << std::endl;
28
29 // 逻辑非运算
30 std::transform(vec1.begin(), vec1.end(), result.begin(),
31 std::logical_not<bool>());
32
33 for (bool val : result) {
34 std::cout << val << " "; // 输出: 0 1 0 1
35 }
36 std::cout << std::endl;
37
38 return 0;
39}
xxxxxxxxxx
361
2
3
4
5// 判断是否为偶数
6struct IsEven {
7 bool operator()(int n) const {
8 return n % 2 == 0;
9 }
10};
11
12// 平方运算
13struct Square {
14 int operator()(int n) const {
15 return n * n;
16 }
17};
18
19int main() {
20 std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
21
22 // 计算偶数个数
23 int evenCount = std::count_if(numbers.begin(), numbers.end(), IsEven());
24 std::cout << "偶数个数: " << evenCount << std::endl; // 输出: 5
25
26 // 计算平方
27 std::vector<int> squares(numbers.size());
28 std::transform(numbers.begin(), numbers.end(), squares.begin(), Square());
29
30 for (int sq : squares) {
31 std::cout << sq << " "; // 输出: 1 4 9 16 25 36 49 64 81 100
32 }
33 std::cout << std::endl;
34
35 return 0;
36}
xxxxxxxxxx
581
2
3
4
5// 累加器函数对象
6class Accumulator {
7public:
8 Accumulator(int initial = 0) : sum_(initial) {}
9
10 int operator()(int value) {
11 sum_ += value;
12 return sum_;
13 }
14
15 int getSum() const { return sum_; }
16
17private:
18 int sum_;
19};
20
21// 计数器函数对象
22class Counter {
23public:
24 Counter() : count_(0) {}
25
26 bool operator()(int value) {
27 count_++;
28 return value > 0; // 示例:计算正数
29 }
30
31 int getCount() const { return count_; }
32
33private:
34 int count_;
35};
36
37int main() {
38 std::vector<int> numbers = {1, -2, 3, -4, 5, 6, -7, 8};
39
40 // 使用累加器
41 Accumulator acc(0);
42 std::vector<int> cumulative(numbers.size());
43 std::transform(numbers.begin(), numbers.end(), cumulative.begin(),
44 std::ref(acc)); // 使用std::ref保持状态
45
46 std::cout << "累积和: ";
47 for (int val : cumulative) {
48 std::cout << val << " "; // 输出: 1 -1 2 -2 3 9 2 10
49 }
50 std::cout << std::endl;
51
52 // 使用计数器
53 Counter counter;
54 std::count_if(numbers.begin(), numbers.end(), std::ref(counter));
55 std::cout << "处理的元素个数: " << counter.getCount() << std::endl; // 输出: 8
56
57 return 0;
58}
xxxxxxxxxx
721
2
3
4
5// 范围检查函数对象
6class InRange {
7public:
8 InRange(int min, int max) : min_(min), max_(max) {}
9
10 bool operator()(int value) const {
11 return value >= min_ && value <= max_;
12 }
13
14private:
15 int min_, max_;
16};
17
18// 倍数检查函数对象
19class IsMultipleOf {
20public:
21 IsMultipleOf(int divisor) : divisor_(divisor) {}
22
23 bool operator()(int value) const {
24 return value % divisor_ == 0;
25 }
26
27private:
28 int divisor_;
29};
30
31// 字符串长度比较
32class StringLengthCompare {
33public:
34 StringLengthCompare(bool ascending = true) : ascending_(ascending) {}
35
36 bool operator()(const std::string& a, const std::string& b) const {
37 if (ascending_) {
38 return a.length() < b.length();
39 } else {
40 return a.length() > b.length();
41 }
42 }
43
44private:
45 bool ascending_;
46};
47
48int main() {
49 std::vector<int> numbers = {1, 5, 10, 15, 20, 25, 30, 35, 40};
50
51 // 查找10-30范围内的数字
52 auto it = std::find_if(numbers.begin(), numbers.end(), InRange(10, 30));
53 if (it != numbers.end()) {
54 std::cout << "找到范围内的数字: " << *it << std::endl; // 输出: 10
55 }
56
57 // 计算5的倍数个数
58 int count = std::count_if(numbers.begin(), numbers.end(), IsMultipleOf(5));
59 std::cout << "5的倍数个数: " << count << std::endl; // 输出: 8
60
61 // 字符串按长度排序
62 std::vector<std::string> words = {"apple", "cat", "elephant", "dog", "bird"};
63
64 std::sort(words.begin(), words.end(), StringLengthCompare(true));
65 std::cout << "按长度升序: ";
66 for (const auto& word : words) {
67 std::cout << word << " "; // 输出: cat dog bird apple elephant
68 }
69 std::cout << std::endl;
70
71 return 0;
72}
xxxxxxxxxx
291
2
3
4
5
6struct FindFirstNegative {
7 bool operator()(int value) const {
8 return value < 0;
9 }
10};
11
12int main() {
13 std::vector<int> numbers = {1, 3, -2, 5, -7, 8};
14
15 // 查找第一个负数
16 auto it = std::find_if(numbers.begin(), numbers.end(), FindFirstNegative());
17 if (it != numbers.end()) {
18 std::cout << "第一个负数: " << *it << std::endl; // 输出: -2
19 }
20
21 // 使用标准函数对象查找大于5的数
22 auto it2 = std::find_if(numbers.begin(), numbers.end(),
23 std::bind(std::greater<int>(), std::placeholders::_1, 5));
24 if (it2 != numbers.end()) {
25 std::cout << "第一个大于5的数: " << *it2 << std::endl; // 输出: 8
26 }
27
28 return 0;
29}
xxxxxxxxxx
451
2
3
4
5
6// 按绝对值排序
7struct AbsoluteCompare {
8 bool operator()(int a, int b) const {
9 return std::abs(a) < std::abs(b);
10 }
11};
12
13// 按字符串长度然后字典序排序
14struct StringCompare {
15 bool operator()(const std::string& a, const std::string& b) const {
16 if (a.length() != b.length()) {
17 return a.length() < b.length();
18 }
19 return a < b;
20 }
21};
22
23int main() {
24 // 按绝对值排序
25 std::vector<int> numbers = {-5, 2, -1, 8, -3, 6};
26 std::sort(numbers.begin(), numbers.end(), AbsoluteCompare());
27
28 std::cout << "按绝对值排序: ";
29 for (int num : numbers) {
30 std::cout << num << " "; // 输出: -1 2 -3 -5 6 8
31 }
32 std::cout << std::endl;
33
34 // 字符串复合排序
35 std::vector<std::string> words = {"apple", "cat", "dog", "elephant", "ant", "bird"};
36 std::sort(words.begin(), words.end(), StringCompare());
37
38 std::cout << "复合排序: ";
39 for (const auto& word : words) {
40 std::cout << word << " "; // 输出: ant cat dog bird apple elephant
41 }
42 std::cout << std::endl;
43
44 return 0;
45}
xxxxxxxxxx
371
2
3
4
5
6// 自定义累积函数对象
7struct Product {
8 int operator()(int a, int b) const {
9 return a * b;
10 }
11};
12
13// 条件累积
14struct ConditionalSum {
15 int operator()(int sum, int value) const {
16 return (value > 0) ? sum + value : sum;
17 }
18};
19
20int main() {
21 std::vector<int> numbers = {1, 2, 3, 4, 5};
22
23 // 计算乘积
24 int product = std::accumulate(numbers.begin(), numbers.end(), 1, Product());
25 std::cout << "乘积: " << product << std::endl; // 输出: 120
26
27 // 使用标准函数对象
28 int sum = std::accumulate(numbers.begin(), numbers.end(), 0, std::plus<int>());
29 std::cout << "和: " << sum << std::endl; // 输出: 15
30
31 // 条件累积(只累加正数)
32 std::vector<int> mixed = {-2, 3, -1, 4, -5, 6};
33 int positiveSum = std::accumulate(mixed.begin(), mixed.end(), 0, ConditionalSum());
34 std::cout << "正数和: " << positiveSum << std::endl; // 输出: 13
35
36 return 0;
37}