当前位置: 首页 > news >正文

C++ 学习之函数对象

在这里插入图片描述

C++ 函数对象基本概念

在C++中,函数对象(Function Objects)是一种类或结构体,它重载了函数调用运算符operator(),因此可以像函数一样被调用。函数对象有时也被称为仿函数(Functor)。

以下是关于C++函数对象的基本概念:

  1. 使用函数对象:函数对象可以像普通函数一样被调用,通过在对象后加括号并传递参数来执行操作。例如:

    #include <iostream>struct Add {int operator()(int a, int b) { return a + b; }
    };int main() {Add adder;std::cout << adder(3, 4) << std::endl;  // 调用函数对象return 0;
    }
    
  2. 重载operator():函数对象需要重载operator(),并根据需要定义参数和返回值。通过重载operator(),函数对象就可以像函数一样被调用。

  3. 状态保持:与普通函数不同的是,函数对象可以包含状态。这意味着函数对象可以在其内部保持一些状态信息,并在每次调用时进行更新。这使得函数对象更加灵活且功能强大。

  4. 模板函数对象:函数对象可以是模板类,可以接受不同类型的参数。这样可以实现更通用和灵活的函数对象,适用于多种情况。

  5. 标准库中的函数对象:C++标准库提供了许多预定义的函数对象,如std::plusstd::minusstd::greater等,可以直接使用这些函数对象完成特定的操作,而不用自己定义函数对象。

  6. 使用场景:函数对象通常用于泛型编程、STL算法、排序、自定义比较函数等情况。通过函数对象,我们可以定义自己的函数行为,并将其应用于各种数据结构和算法中。

通过函数对象,C++提供了一种更加灵活和可定制的函数调用方式,使编程变得更加方便和高效。

C++ 函数对象使用

在C++中,函数对象(Function Objects)可以通过类或结构体重载operator()来实现,从而使其像函数一样被调用。使用函数对象可以提供更灵活和通用的函数行为,适用于各种情况。以下是一些关于如何定义和使用函数对象的示例:
在这里插入图片描述

示例1:定义一个简单的函数对象并调用

#include <iostream>// 定义一个加法函数对象
struct Add {int operator()(int a, int b) {return a + b;}
};int main() {Add adder; // 创建函数对象int result = adder(3, 4); // 调用函数对象std::cout << "Result: " << result << std::endl;return 0;
}

示例2:利用函数对象实现自定义排序

#include <iostream>
#include <vector>
#include <algorithm>// 自定义升序排序函数对象
struct AscendingOrder {bool operator()(int a, int b) {return a < b;}
};int main() {std::vector<int> numbers = {5, 2, 8, 1, 4};// 使用函数对象进行升序排序AscendingOrder ascending_order;std::sort(numbers.begin(), numbers.end(), ascending_order);// 输出排序结果for (int num : numbers) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

示例3:利用标准库提供的函数对象

#include <iostream>
#include <algorithm>
#include <vector>int main() {std::vector<int> numbers = {5, 2, 8, 1, 4};// 使用标准库提供的函数对象std::greater进行降序排序std::sort(numbers.begin(), numbers.end(), std::greater<int>());// 输出排序结果for (int num : numbers) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

通过这些示例,您可以看到如何定义和使用函数对象来实现自定义操作、排序、比较等功能。函数对象在STL算法、泛型编程、模板编程等方面有着广泛的应用,能够使代码更通用、可复用和高效。

C++ 一元谓词

在这里插入图片描述

在C++中,一元谓词(Unary Predicate)是一个函数对象或函数指针,它接受一个参数并返回一个bool值。一元谓词通常用于标准库算法中,作为条件判断或过滤的依据。一元谓词的主要特点是只接受一个参数。

下面是一个简单的示例来说明一元谓词的用法:

#include <iostream>
#include <vector>
#include <algorithm>// 一元谓词函数对象,用于判断一个整数是否为偶数
struct IsEven {bool operator()(int n) {return n % 2 == 0;}
};int main() {std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9};// 使用一元谓词IsEven进行筛选,只保留偶数auto it = std::remove_if(numbers.begin(), numbers.end(), IsEven());// 调用erase方法擦除不符合条件的元素numbers.erase(it, numbers.end());// 输出结果for(int num : numbers) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

在这个示例中,我们定义了一个一元谓词函数对象IsEven,它判断一个整数是否为偶数。然后我们使用std::remove_if算法结合该一元谓词对容器numbers进行筛选,去除所有不满足条件的元素,最后输出剩余的偶数。

一元谓词在很多情况下都非常有用,可以帮助我们根据自定义的条件来进行数据筛选、操作等。通过使用一元谓词,您可以更灵活地控制算法的行为,并适应各种需求。

C++ 二元谓词

在C++中,二元谓词(Binary Predicate)是一个函数对象或函数指针,它接受两个参数并返回一个bool值。二元谓词通常在标准库算法中使用,用于比较两个元素或判断它们之间的关系。

下面是一个简单的示例来说明二元谓词的用法:

#include <iostream>
#include <vector>
#include <algorithm>// 二元谓词函数对象,用于比较两个整数的大小关系
struct Compare {bool operator()(int a, int b) {return a < b;}
};int main() {std::vector<int> numbers = {4, 2, 7, 3, 9, 5};// 使用二元谓词Compare进行排序std::sort(numbers.begin(), numbers.end(), Compare());// 输出排序结果for (int num : numbers) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

在这个示例中,我们定义了一个二元谓词函数对象Compare,它比较两个整数的大小关系。然后我们使用std::sort算法结合该二元谓词对容器numbers进行排序,按照自定义的比较函数对象来重新排列元素顺序。

二元谓词在排序、查找、删除等需要考虑元素之间关系的情况下非常有用。通过提供自定义的二元谓词,我们可以灵活地控制算法的行为,满足各种不同的需求。

C++ 函数对象算数仿函数

函数对象(Function Objects)在C++中也可以作为算术仿函数(Arithmetic Functors)使用,它们模拟了基本的算术操作符(如加法、减法、乘法和除法),使其能够像函数一样被调用。

以下是一些示例说明如何使用函数对象作为算术仿函数:

示例1:使用函数对象实现加法仿函数

#include <iostream>// 定义一个加法仿函数
struct Add {int operator()(int a, int b) const {return a + b;}
};int main() {Add adder; // 创建加法仿函数对象int result = adder(3, 4); // 调用加法仿函数std::cout << "Result: " << result << std::endl;return 0;
}

示例2:使用函数对象实现乘法仿函数

#include <iostream>// 定义一个乘法仿函数
struct Multiply {int operator()(int a, int b) const {return a * b;}
};int main() {Multiply multiplier; // 创建乘法仿函数对象int result = multiplier(3, 4); // 调用乘法仿函数std::cout << "Result: " << result << std::endl;return 0;
}

示例3:使用标准库提供的算术仿函数

#include <iostream>
#include <functional>int main() {std::plus<int> adder; // 创建加法仿函数对象int result = adder(3, 4); // 调用加法仿函数std::cout << "Result: " << result << std::endl;std::multiplies<int> multiplier; // 创建乘法仿函数对象result = multiplier(3, 4); // 调用乘法仿函数std::cout << "Result: " << result << std::endl;return 0;
}

通过这些示例,您可以看到如何使用函数对象作为算术仿函数,从而进行加法和乘法运算。您可以自定义函数对象来实现更复杂的算术操作,或者使用标准库提供的算术仿函数(如std::plusstd::multiplies)来简化代码。

C++ 函数对象关系仿函数

函数对象关系仿函数(Function Object Relational Functors)用于比较两个对象之间的关系,例如相等、不相等、大于、小于等。它们通常被用于需要排序、查找或筛选操作中。

以下是一些示例说明如何使用函数对象关系仿函数:

示例1:使用函数对象关系仿函数进行相等判断

#include <iostream>
#include <functional>int main() {std::equal_to<int> isEqual; // 创建相等仿函数对象bool result = isEqual(3, 4); // 判断两个数是否相等std::cout << "Is equal: " << std::boolalpha << result << std::endl;return 0;
}

示例2:使用函数对象关系仿函数进行大小比较

#include <iostream>
#include <functional>int main() {std::greater<int> isGreater; // 创建大于仿函数对象bool result = isGreater(3, 4); // 判断第一个数是否大于第二个数std::cout << "Is greater: " << std::boolalpha << result << std::endl;std::less<int> isLess; // 创建小于仿函数对象result = isLess(3, 4); // 判断第一个数是否小于第二个数std::cout << "Is less: " << std::boolalpha << result << std::endl;return 0;
}

示例3:自定义函数对象关系仿函数进行字符串长度比较

#include <iostream>
#include <string>// 自定义字符串长度比较仿函数
struct StringLengthComparator {bool operator()(const std::string& str1, const std::string& str2) const {return str1.length() < str2.length();}
};int main() {StringLengthComparator compareLength; // 创建字符串长度比较仿函数对象bool result = compareLength("apple", "banana"); // 判断第一个字符串的长度是否小于第二个字符串的长度std::cout << "Is length less: " << std::boolalpha << result << std::endl;return 0;
}

通过这些示例,您可以看到如何使用函数对象关系仿函数来进行对象之间的关系判断。您可以使用标准库提供的函数对象关系仿函数(如std::equal_tostd::greaterstd::less),也可以自定义函数对象关系仿函数来满足特定需求。

C++ 函数对象逻辑仿函数

函数对象逻辑仿函数(Function Object Logical Functors)用于执行逻辑运算,比如逻辑与、逻辑或、逻辑非等操作。它们通常被用于需要对多个条件进行组合判断的情况。

以下是一些示例说明如何使用函数对象逻辑仿函数:

示例1:使用函数对象逻辑仿函数进行逻辑与操作

#include <iostream>
#include <functional>int main() {std::logical_and<bool> andOp; // 创建逻辑与仿函数对象bool result = andOp(true, false); // 判断两个条件是否同时为真std::cout << "Logical AND result: " << std::boolalpha << result << std::endl;return 0;
}

示例2:使用函数对象逻辑仿函数进行逻辑或操作

#include <iostream>
#include <functional>int main() {std::logical_or<bool> orOp; // 创建逻辑或仿函数对象bool result = orOp(true, false); // 判断两个条件是否至少有一个为真std::cout << "Logical OR result: " << std::boolalpha << result << std::endl;return 0;
}

示例3:自定义函数对象逻辑仿函数进行逻辑非操作

#include <iostream>// 自定义逻辑非仿函数
struct LogicalNot {bool operator()(bool value) const {return !value;}
};int main() {LogicalNot notOp; // 创建逻辑非仿函数对象bool result = notOp(true); // 对给定条件取逻辑非std::cout << "Logical NOT result: " << std::boolalpha << result << std::endl;return 0;
}

通过这些示例,您可以看到如何使用函数对象逻辑仿函数来执行逻辑运算。您可以使用标准库提供的逻辑仿函数(如std::logical_andstd::logical_or),也可以自定义函数对象逻辑仿函数来实现特定的逻辑操作。

关注我,不迷路,共学习,同进步

在这里插入图片描述

关注我,不迷路,共学习,同进步

相关文章:

  • Stable Diffusion 绘画入门教程(webui)-ControlNet(深度Depth)
  • Day13-Linux系统用户管理知识精讲2
  • Java架构师之路六、高并发与性能优化:高并发编程、性能调优、线程池、NIO、Netty、高性能数据库等。
  • Movelt使用笔记-Movelt Setup Assistant
  • C# OpenCvSharp Tracker 目标追踪
  • ✅技术社区项目—JWT身份验证
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • 【黑马程序员】2、TypeScript介绍_黑马程序员前端TypeScript教程,TypeScript零基础入门到实战全套教程
  • 【论文精读】ConvNeXt
  • 2.26作业
  • Kafka3.x进阶
  • 百亿大佬南存辉瞄准光伏板块,正泰电器分拆正泰安能上市
  • Android的LiveData
  • 机器学习理论知识学习
  • 化学分子Mol2文件格式与使用注意事项
  • JavaScript 如何正确处理 Unicode 编码问题!
  • $translatePartialLoader加载失败及解决方式
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • JavaScript实现分页效果
  • Java程序员幽默爆笑锦集
  • JAVA多线程机制解析-volatilesynchronized
  • java正则表式的使用
  • JAVA之继承和多态
  • Less 日常用法
  • nfs客户端进程变D,延伸linux的lock
  • SpiderData 2019年2月16日 DApp数据排行榜
  • V4L2视频输入框架概述
  • 初识 beanstalkd
  • 和 || 运算
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 它承受着该等级不该有的简单, leetcode 564 寻找最近的回文数
  • 移动互联网+智能运营体系搭建=你家有金矿啊!
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • #Linux(make工具和makefile文件以及makefile语法)
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (2)MFC+openGL单文档框架glFrame
  • (C语言)编写程序将一个4×4的数组进行顺时针旋转90度后输出。
  • (编译到47%失败)to be deleted
  • (二)换源+apt-get基础配置+搜狗拼音
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (附源码)基于SpringBoot和Vue的厨到家服务平台的设计与实现 毕业设计 063133
  • (附源码)计算机毕业设计SSM疫情社区管理系统
  • (转)大型网站的系统架构
  • (转)项目管理杂谈-我所期望的新人
  • (转载)跟我一起学习VIM - The Life Changing Editor
  • .NET 3.0 Framework已经被添加到WindowUpdate
  • .NET 5.0正式发布,有什么功能特性(翻译)
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .NET Core工程编译事件$(TargetDir)变量为空引发的思考
  • .NET Core中Emit的使用
  • .NET delegate 委托 、 Event 事件
  • .NET 中 GetHashCode 的哈希值有多大概率会相同(哈希碰撞)
  • .NET框架设计—常被忽视的C#设计技巧