浅谈STL|STL函数对象篇

在这里插入图片描述

一.函数对象概念

概念:

·重载函数调用操作符的类,其对象常称为函数对象
·函数对象使用重载的()时,行为类似函数调用,也叫仿函数

本质:

函数对象(仿函数)是一个类,不是一个函数

特点

  • 函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值;
  • 函数对象超出普通函数的概念,函数对象可以有自己的状态;
  • 函数对象可以作为参数传递;

函数对象可以像普通函数一样被调用,并且可以接受参数和返回值。通过重载函数调用操作符 operator(),函数对象可以在使用时表现得像函数一样。

函数对象的一个优势是它可以拥有自己的状态。由于函数对象实际上是一个类的对象,所以它可以拥有成员变量,这些变量可以在每次调用时保持状态并进行更新。这使得函数对象可以在多次调用之间维护一些信息。

此外,函数对象还可以作为参数传递给其他函数。许多标准库的算法函数,例如 std::sortstd::transform 等,可以接受函数对象作为参数,以定义算法的具体操作。通过将函数对象传递给其他函数,我们可以实现更灵活、可定制的功能。

以下是一个简单的示例,展示了函数对象的用法:

#include <iostream>class MyFunctor
{
public:void operator()(int x) const{// 在回调时输出消息std::cout << "Function object called with " << x << std::endl;}
};void callWithFunctor(const MyFunctor& functor, int value)
{functor(value);  // 调用函数对象
}int main()
{MyFunctor functor;callWithFunctor(functor, 42);  // 传递函数对象给函数,并进行调用return 0;
}

在上述示例中,MyFunctor 是一个函数对象,我们将它作为参数传递给 callWithFunctor 函数,并在函数内部调用函数对象。

总结来说,函数对象可以像普通函数一样被调用,可以接受参数和返回值,可以拥有自己的状态,并可以作为参数传递给其他函数,这使得函数对象在编程中非常有用和灵活。


函数对象相比于普通函数具有一个重要的优势,那就是函数对象可以拥有自己的状态。这意味着函数对象可以在多次调用之间记录和维护自己的内部数据。

普通函数是无状态的,它们不会保留任何关于之前调用的信息。每次调用函数时,它们只是根据传入的参数执行相应的操作,并返回结果。

而函数对象则可以在每次调用时保持状态,并根据状态的变化来改变行为。这种状态是通过函数对象的成员变量来实现的。函数对象的成员变量可以记录在调用过程中需要持久化的数据,而这些数据会在不同的函数调用之间持续存在。

这种函数对象的状态可以非常有用。它允许我们在不同的调用之间共享和利用数据,从而实现更复杂的行为。例如,我们可以使用函数对象来实现一个计数器,每次调用增加计数值,并在后续的调用中使用该值。

以下是一个简单的示例,展示了函数对象中保存状态的功能:

#include <iostream>class Counter
{
public:Counter() : count(0) {}int operator()(){return ++count;}private:int count;
};int main()
{Counter counter;std::cout << counter() << std::endl;  // 输出:1std::cout << counter() << std::endl;  // 输出:2std::cout << counter() << std::endl;  // 输出:3return 0;
}

在上述示例中,Counter 是一个函数对象,它通过重载函数调用操作符 operator() 来实现计数的功能。每次调用 Counter 对象时,计数器的值会增加,并返回新的计数值。

总结而言,函数对象相比普通函数具有自己的状态,这使得它们可以在多次调用之间保持数据,并根据状态的变化改变行为。这种功能使得函数对象在许多应用场景中非常有用,例如实现计数器、缓存等。

二.谓词

概念:

  • 返回bool类型的仿函数称为谓词
  • 如果operator()接受一个参数,那么叫做一元谓词
  • 如果operator()接受两个参数,那么叫做二元谓词

返回 bool 类型的仿函数被称为谓词(Predicate)。谓词通常用于对某些条件进行判断,并返回相应的布尔值。

此外,根据 operator() 接受的参数数量,可以将谓词进一步分类为一元谓词(Unary Predicate)和二元谓词(Binary Predicate)。

  • 一元谓词是指 operator() 只接受一个参数的谓词。它用于对单个对象进行判断,返回一个布尔值。一元谓词通常用于像 std::find_ifstd::remove_if 等算法中。
  • 二元谓词是指 operator() 接受两个参数的谓词。它用于对两个对象进行比较或判断,返回一个布尔值。二元谓词通常用于像 std::sortstd::find 等算法中,用于指定排序规则或比较条件。

通过使用谓词,我们可以灵活地对对象进行条件判断和过滤。

以下是一个简单的示例,展示了一元谓词和二元谓词的概念:

#include <iostream>
#include <vector>
#include <algorithm>// 一元谓词
struct IsEven
{bool operator()(int n) const{return n % 2 == 0;}
};// 二元谓词
struct IsLess
{bool operator()(int a, int b) const{return a < b;}
};int main()
{std::vector<int> numbers = { 1, 2, 3, 4, 5 };// 使用一元谓词查找第一个偶数auto it = std::find_if(numbers.begin(), numbers.end(), IsEven());if (it != numbers.end()){std::cout << "First even number: " << *it << std::endl;}// 使用二元谓词排序std::sort(numbers.begin(), numbers.end(), IsLess());// 输出排序结果std::cout << "Sorted numbers: ";for (int num : numbers){std::cout << num << " ";}std::cout << std::endl;return 0;
}

在上述示例中,IsEven 是一个一元谓词,通过重载 operator() 来判断一个数字是否为偶数。IsLess 是一个二元谓词,通过重载 operator() 实现了两个数字的比较操作。

我们在主函数中使用了一元谓词来查找第一个偶数,并使用二元谓词对数组进行排序。

总结来说,返回 bool 类型的函数对象被称为谓词。根据 operator() 接受的参数数量,谓词可以进一步分类为一元谓词和二元谓词。谓词在标准库的算法中大量使用,用于自定义比较和条件判断。


find_if

std::find_if 是 C++ 标准库中的一个算法函数,它的作用是在给定的范围内查找满足指定条件的元素,并返回第一个满足条件的元素的迭代器。

函数签名如下所示:

template <class InputIt, class UnaryPredicate>
InputIt find_if(InputIt first, InputIt last, UnaryPredicate p);

参数说明:

  • firstlast:表示要查找的元素范围,first 表示范围的起始位置,last 表示范围的结束位置(不包含在范围内)。
  • p:一个一元谓词,用于判断元素是否满足条件。

函数返回值是一个迭代器,指向范围内第一个满足条件的元素,如果没有找到满足条件的元素,则返回 last

以下是一个简单的示例,展示了 std::find_if 的使用:

#include <iostream>
#include <vector>
#include <algorithm>struct IsEven
{bool operator()(int n) const{return n % 2 == 0;}
};int main()
{std::vector<int> numbers = { 1, 2, 3, 4, 5 };// 使用一元谓词查找第一个偶数auto it = std::find_if(numbers.begin(), numbers.end(), IsEven());if (it != numbers.end()){std::cout << "First even number: " << *it << std::endl;}return 0;
}

在上述示例中,我们定义了一个一元谓词 IsEven,用于判断一个数字是否为偶数。然后,我们使用 std::find_if 函数在 numbers 容器中查找第一个满足条件的偶数,并输出结果。

值得注意的是,std::find_if 在查找到满足条件的元素后,会立即停止搜索并返回该元素的迭代器。如果要查找出多个满足条件的元素,可以使用 std::find_if 结合其他算法函数或循环进行迭代查找。

三.内建函数对象

当涉及到内建函数对象时,可以根据它们的功能将它们分为三类: 算术函数对象、逻辑函数对象和关系函数对象。

  1. 算术函数对象:

    • std::plus: 加法操作。
    • std::minus: 减法操作。
    • std::multiplies: 乘法操作。
    • std::divides: 除法操作。
    • std::modulus: 取模操作。
  2. 逻辑函数对象:

    • std::logical_and: 逻辑与操作。
    • std::logical_or: 逻辑或操作。
    • std::logical_not: 逻辑非操作。
  3. 关系函数对象:

    • std::less: 小于比较。
    • std::less_equal: 小于等于比较。
    • std::greater: 大于比较。
    • std::greater_equal: 大于等于比较。
    • std::equal_to: 等于比较。
    • std::not_equal_to: 不等于比较。

这些函数对象可以通过重载 operator() 来执行特定的操作或比较,它们被设计为与标准库算法一起使用,以提供通用的功能。通过使用这些函数对象,我们可以以一种通用且灵活的方式处理算术、逻辑和关系操作。

当涉及到内建函数对象时,我们可以通过以下示例来展示它们的使用:

  1. 算术函数对象:
#include <iostream>
#include <functional>int main() {std::plus<int> add;int a = 5, b = 10;int result = add(a, b);std::cout << "Addition result: " << result << std::endl;  // 输出:15return 0;
}

在上述示例中,我们使用了 std::plus 函数对象来执行加法操作,将数字 ab 相加,并将结果存储在 result 变量中。

  1. 逻辑函数对象:
#include <iostream>
#include <functional>int main() {std::logical_and<bool> logicAnd;bool value1 = true, value2 = false;bool result = logicAnd(value1, value2);std::cout << "Logical AND result: " << std::boolalpha << result << std::endl;  // 输出:falsereturn 0;
}

在上述示例中,我们使用了 std::logical_and 函数对象来执行逻辑与操作,对 value1value2 进行逻辑与运算,并将结果存储在 result 变量中。

  1. 关系函数对象:
#include <iostream>
#include <functional>int main() {std::less<int> lessThan;int a = 5, b = 10;bool result = lessThan(a, b);std::cout << "Less than result: " << std::boolalpha << result << std::endl;  // 输出:truereturn 0;
}

在上述示例中,我们使用了 std::less 函数对象来执行小于比较,判断 a 是否小于 b,并将结果存储在 result 变量中。

这些示例演示了如何使用内建函数对象进行算术、逻辑和关系操作。您可以通过实例化适当的函数对象类模板,然后将其用作函数调用,以便执行所需的操作或比较。

请注意,这些示例可能只是演示了函数对象的一小部分用法,这些函数对象在标准库的算法和其他使用场景中非常有用。

好的,下面是一个整理成表格的例子,展示了内建函数对象及其用途的示例。

函数对象用途示例
std::plus加法操作std::plus()(2, 3) // 输出:5
std::minus减法操作std::minus()(5, 2) // 输出:3
std::multiplies乘法操作std::multiplies()(3, 4) // 输出:12
std::divides除法操作std::divides()(10, 2) // 输出:5
std::modulus取模操作std::modulus()(10, 3) // 输出:1
std::logical_and逻辑与操作std::logical_and()(true, false) // 输出:false
std::logical_or逻辑或操作std::logical_or()(true, false) // 输出:true
std::logical_not逻辑非操作std::logical_not()(true) // 输出:false
std::less小于比较std::less()(2, 5) // 输出:true
std::less_equal小于等于比较std::less_equal()(5, 5) // 输出:true
std::greater大于比较std::greater()(5, 2) // 输出:true
std::greater_equal大于等于比较std::greater_equal()(5, 5) // 输出:true
std::equal_to相等比较std::equal_to()(2, 2) // 输出:true
std::not_equal_to不等比较std::not_equal_to()(2, 5) // 输出:true

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/78516.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux提权

shell分本地shell 和 webshell 有些提权方式只能本地shell使用 常见内核漏洞查找脚本以及利用 环境变量提权 suid https://www.cnblogs.com/banglook/archive/2022/03/17/16019354.html linux特殊命令https://www.secrss.com/articles/28493 什么是suid SUID (Set UID)是Li…

「中秋来袭」没想到,用OpenCV竟能画出这么漂亮的月饼「附源码」

一、前言 中秋佳节即将来临&#xff0c;作为传统的中国节日之一&#xff0c;人们除了品尝美味的月饼、赏月外&#xff0c;还喜欢通过绘画来表达对这个节日的喜悦和祝福。而如今&#xff0c;随着科技的不断发展&#xff0c;竟然可以借助计算机视觉库OpenCV来绘制精美的月饼和可…

Redis的数据持久化方案

目录 前言 RDB方式 概述&#xff1a; 1.RDB手动 &#xff12;.RDB自动 RDB优缺点 AOF方式 概述 AOF写数据的三种策略 AOF相关配置 AOF重写 AOF重写方式 手动重写 bgrewriteaof 自动重写 总结 前言 Redis是一个内存型数据库&#xff0c;也就是说如果不将内存中的…

被删除并且被回收站清空的文件如何找回

文件的意外删除和回收站清空是许多用户面临的普遍问题。这种情况下&#xff0c;很多人会感到无助和焦虑&#xff0c;担心自己的重要文件永远丢失。然而&#xff0c;幸运的是&#xff0c;依然存在一些有效的方法能够帮助我们找回被删除并且被回收站清空的文件。 ▌被删除文件在…

uniapp——实现聊天室功能——技能提升

这里写目录标题 效果图聊天室功能代码——html部分代码——js部分代码——其他部分 首先声明一点&#xff1a;下面的内容是从一个uniapp的程序中摘录的&#xff0c;并非本人所写&#xff0c;先做记录&#xff0c;以免后续遇到相似需求抓耳挠腮。 效果图 聊天室功能 发送图片 …

进制转换问题

进制 二进制 &#xff08;Binary&#xff09;&#xff1a;0、1。简写为B 八进制&#xff08;Octonary&#xff09;&#xff1a;0、1、2、3、4、5、6、7。简写为O 十进制&#xff08;decimalism&#xff09;&#xff1a;0、1、2、3、4、5、6、7、8、9 简写为D 十六进制&#xff…

【建议收藏】职场人口头和书面沟通必备词语,瞬间高大上

这年头&#xff0c;在职场不但要会做&#xff0c;还要会说。 会说还不能平铺直叙的说&#xff0c;还要能把普通的工作说出话来&#xff0c;这就需要一些“考究”的用词。尤其是在某些头部企业的带领下&#xff0c;业务不够、产品不行、解决方案不够新&#xff0c;就用华丽的辞…

ASEMI二极管1N4148(T4)的用途和使用建议

编辑-Z 二极管是一种常见的电子元件&#xff0c;其中1N4148&#xff08;T4&#xff09;是一款广泛使用的快恢复二极管。它具有快速的开关特性和高反向阻挡能力&#xff0c;适用于多种电子应用。本文将介绍1N4148&#xff08;T4&#xff09;的特点、用途和如何正确使用该二极管…

如何使用极狐GitLab 支持 ISO 27001 合规

目录 组织控制 技术控制 了解更多 本文来源&#xff1a;about.gitlab.com 作者&#xff1a;Joseph Longo 译者&#xff1a;武让 极狐GitLab 高级解决方案架构师 作为一体化平台&#xff0c;通过极狐GitLab 可以很容易实现 DevSecOps 全生命周期管理。极狐GitLab 使开发人员能…

无涯教程-JavaScript - FALSE函数

描述 FALSE函数返回逻辑值FALSE。 语法 FALSE () 争论 FALSE函数没有参数。 Notes 您还可以在工作表或公式中直接键入FALSE单词,Microsoft Excel会将其解释为逻辑值FALSE。 提供FALSE功能主要是为了与其他电子表格程序兼容。 适用性 Excel 2007,Excel 2010,Excel 2013…

webhook--详解(gitee 推送)

一、简介 webhook 是一种基于 HTTP 的回调函数&#xff0c;可在 2 个应用编程接口&#xff08;API&#xff09;之间实现轻量级的事件驱动通信。是一种新型的前后端交互方式&#xff0c;一种对客户端-服务器模式的逆转&#xff0c;在传统方法中&#xff0c;客户端从服务器请求数…

怎样做一个简易而温馨的原木风居室空间

由 balbek bureau 设计的 Relogged 是一座重新设计的私人住宅&#xff0c;位于乌克兰河岸的绿化区。顾名思义&#xff0c;该项目重新诠释了木屋的概念&#xff0c;并与充满自然气息的环境相呼应&#xff0c;营造出宁静舒适的生活氛围。在探索重新设计的木屋实例时&#xff0c;建…

设计模式:享元模式

设计模式&#xff1a;享元模式 什么是享元模式 首先我们需要简单了解一下什么是享元模式。享元模式(Flyweight Pattern):主要用于减少创建对象的数量&#xff0c;以减少内存占用和提高性能。享元模式的重点就在这个享字&#xff0c;通过一些共享技术来减少对象的创建&#xff…

《Web安全基础》04. 文件操作安全

web 1&#xff1a;文件操作安全2&#xff1a;文件上传漏洞2.1&#xff1a;简介2.2&#xff1a;防护与绕过2.3&#xff1a;WAF 绕过2.3.1&#xff1a;数据溢出2.3.2&#xff1a;符号变异2.3.3&#xff1a;数据截断2.3.4&#xff1a;重复数据 3&#xff1a;文件包含漏洞4&#xf…

7、Spring之依赖注入源码解析(下)

resolveDependency()实现 该方法表示,传入一个依赖描述(DependencyDescriptor),该方法会根据该依赖描述从BeanFactory中找出对应的唯一的一个Bean对象。 @Nullable Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,@Null…

一个最简verilog代码的分析

module testmod( input CLK, output reg [1:0]acc);always(posedge CLK)acc<acc2d1; endmodule 上述代码综合后的电路图为&#xff1a; 分析1 假设在t1时刻&#xff0c;两个触发器的状态都是1&#xff0c;即acc2b11&#xff0c;此时半加器1的A端是1&#xff0c;则D触发器1…

Postman接口压力测试 ---- Tests使用(断言)

所谓断言&#xff0c;主要用于测试返回的数据结果进行匹配判断&#xff0c;匹配成功返回PASS&#xff0c;失败返回FAIL。 下图方法一&#xff0c;直接点击右侧例子函数&#xff0c;会自动生成出现在左侧窗口脚本&#xff0c;只需修改数据即可。 方法二&#xff1a;直接自己写脚…

使用内网端口映射方案,轻松实现U8用友ERP的本地部署异地远程访问——“cpolar内网穿透”

文章目录 前言1. 服务器本机安装U8并调试设置2. 用友U8借助cpolar实现企业远程办公2.1 在被控端电脑上&#xff0c;点击开始菜单栏&#xff0c;打开设置——系统2.2 找到远程桌面2.3 启用远程桌面 3. 安装cpolar内网穿透3.1 注册cpolar账号3.2 下载cpolar客户端 4. 获取远程桌面…

探索装饰艺术的未来,留存传统的精髓

近一个世纪后&#xff0c;装饰艺术终于卷土重来。正如我们在全球新的项目、室内空间和家具中所看到的&#xff0c;那种令我们渴望20世纪初20年代繁荣时期的奢华和魅力。作为装饰艺术建筑和设计的独特身份一直在世界上继续启发着人们&#xff0c;那么从新的设计和现有设计的保留…

从零基础到精通Flutter开发:一步步打造跨平台应用

&#x1f482; 个人网站:【工具大全】【游戏大全】【神级源码资源网】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 寻找学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 导言 Flutter是一种流行…