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

C++STL函数对象的应用

STL函数对象

文章目录

      • STL函数对象
        • 1.基本概念
        • 2.使用方法
          • 1. 简单函数对象示例
          • 2. 函数对象作为算法参数
          • 3. Lambda表达式作为函数对象
        • 2.一元谓词和二元谓词
          • 1.一元谓词
          • 2.二元谓词
          • 3.总结
        • 3.算术仿函数
          • 1.使用示例
          • 2.Lambda表达式的替代
        • 4.关系仿函数
        • 5.逻辑仿函数

C++中的函数对象(Function Object),也常被称为仿函数(Functor),是一种模拟函数行为的类对象。它们允许用户自定义操作,并能像普通函数那样被调用,同时还能携带状态,这是普通函数所不具备的能力。函数对象是实现泛型编程、算法定制等高级技术的关键组件之一。下面概述了函数对象的基本概念和使用方法:

1.基本概念
  1. 类定义:函数对象通常是一个重载了()操作符的类。这个操作符使得该类的对象可以像函数一样被调用。
  2. 状态携带:与普通函数不同,函数对象可以拥有成员变量,从而在不同的调用之间保持状态。
  3. 类型要求:为了能够用于标准库算法中,函数对象需要满足可调用对象的要求,即至少要有一个operator()成员函数。
2.使用方法
1. 简单函数对象示例
#include <iostream>// 定义一个简单的函数对象类,重载了()操作符
class Adder {
public:// 构造函数可以初始化内部状态Adder(int add_value) : value(add_value) {}// 重载()操作符,使得对象可以像函数一样被调用int operator()(int x) {return x + value;}private:int value; // 成员变量,保存加到输入值上的额外值
};int main() {Adder addFive(5); // 创建一个Adder对象,初始化加值为5std::cout << addFive(10) << std::endl; // 调用仿函数,输出15return 0;
}
2. 函数对象作为算法参数

C++标准库中的许多算法都接受函数对象作为参数,以定制其行为。例如,std::sort可以通过传递自定义比较函数来改变排序规则。

#include <algorithm>
#include <vector>
#include <iostream>// 一个用于降序比较的仿函数
struct DescComp {bool operator()(int a, int b) {return a > b;}
};int main() {std::vector<int> vec = {1, 3, 5, 2, 4};// 使用自定义的降序比较仿函数进行排序std::sort(vec.begin(), vec.end(), DescComp());for(int i : vec) {std::cout << i << " ";}// 输出:5 4 3 2 1return 0;
}
3. Lambda表达式作为函数对象

从C++11开始,Lambda表达式提供了一种更简洁的方式创建匿名函数对象,它可以直接在代码中定义并使用。

#include <algorithm>
#include <vector>
#include <iostream>int main() {std::vector<int> vec = {1, 2, 3, 4, 5};// 使用Lambda表达式作为自定义排序规则std::sort(vec.begin(), vec.end(), [](int a, int b) {return a > b; // 降序排列});for(int i : vec) {std::cout << i << " ";}// 输出:5 4 3 2 1return 0;
}

通过上述示例,可以看到函数对象在C++中提供了强大的灵活性和定制能力,是泛型编程和算法设计中的重要工具。

2.一元谓词和二元谓词

C++中的一元谓词和二元谓词是两种特定类型的函数对象,它们在标准模板库(STL)的算法中扮演着重要的角色,用于定制算法的行为。以下是它们的基本概念和使用方法:

1.一元谓词

基本概念:

  • 一元谓词是只接受一个参数的函数对象,并返回一个布尔值(bool)。
  • 这个函数对象通常用来测试或判断传入的参数是否满足某个条件。
  • 在STL算法中,一元谓词常用于从容器中选择满足特定条件的元素,例如std::find_if

使用示例:

#include <algorithm>
#include <vector>
#include <iostream>// 一元谓词函数对象,检查一个数是否为偶数
struct IsEven {bool operator()(int x) {return x % 2 == 0;}
};int main() {std::vector<int> numbers = {1, 2, 3, 4, 5, 6};auto it = std::find_if(numbers.begin(), numbers.end(), IsEven());if(it != numbers.end())std::cout << "The first even number is: " << *it << std::endl;elsestd::cout << "No even number found." << std::endl;return 0;
}
2.二元谓词

基本概念:

  • 二元谓词接受两个参数,并返回一个布尔值。
  • 它们通常用于比较这两个参数是否满足某种关系,如小于、大于、等于等。
  • 在STL中,二元谓词广泛应用于排序算法(如std::sort)、查找算法(如std::binary_search)等,用以定义元素间的比较规则。

使用示例:

#include <algorithm>
#include <vector>
#include <iostream>// 二元谓词函数对象,检查第一个数是否大于第二个数
struct GreaterThan {bool operator()(int a, int b) {return a > b;}
};int main() {std::vector<int> values = {5, 2, 9, 1, 5, 6};// 使用二元谓词进行降序排序std::sort(values.begin(), values.end(), GreaterThan());for(int val : values) {std::cout << val << " ";}// 输出:9 6 5 5 2 1return 0;
}
3.总结

无论是哪种谓词,它们的核心作用都是提供一个逻辑判断,使得STL算法能够基于这些逻辑判断来处理数据。一元谓词适用于单个元素的条件筛选,而二元谓词则用于定义元素间的关系,比如排序或查找时的比较逻辑。随着C++11及之后版本对Lambda表达式的支持,直接在算法中内联定义谓词变得更加方便快捷。

3.算术仿函数

C++ STL(标准模板库)提供了一系列算术仿函数(Arithmetic Functors),它们是对基本数学运算的封装,使得这些运算可以像函数对象一样被使用,尤其是在算法中进行定制操作时非常有用。以下是一些常用的算术仿函数及其简单说明:

  1. plus:定义了加法操作,重载了operator()以执行加法。
  2. minus:定义了减法操作。
  3. multiplies:实现了乘法操作。
  4. divides:提供了除法操作。
  5. modulus:用于取模运算。
  6. negate:执行取负操作。
1.使用示例

这些仿函数位于<functional>头文件。

#include <iostream>
#include <functional>
#include <algorithm> // 用于std::transformint main() {std::vector<int> numbers = {1, 2, 3, 4, 5};std::vector<int> results;// 使用plus仿函数将每个元素自身相加(即每个元素乘以2)results.resize(numbers.size());std::transform(numbers.begin(), numbers.end(), results.begin(), std::plus<int>());// 输出结果for(int res : results) {std::cout << res << " ";}// 输出:2 4 6 8 10return 0;
}

在这个例子中,std::transform算法结合std::plus<int>()仿函数,将numbers容器中的每个元素与其自身相加,结果存储在results容器中。

2.Lambda表达式的替代

虽然算术仿函数非常有用,但在C++11及以后的版本中,Lambda表达式提供了更加灵活和直观的方式来定义这样的操作,特别是在复杂逻辑或需要访问外部变量时。然而,对于简单的数学运算,直接使用STL提供的算术仿函数可以简化代码,提高可读性。

4.关系仿函数

关系仿函数封装了基本的比较运算符,位于<functional>头文件中。

  1. equal_to:测试两个参数是否相等。
  2. not_equal_to:测试两个参数是否不相等。
  3. greater:测试第一个参数是否大于第二个参数。
  4. less:测试第一个参数是否小于第二个参数。
  5. greater_equal:测试第一个参数是否大于等于第二个参数。
  6. less_equal:测试第一个参数是否小于等于第二个参数。
#include <iostream>
#include <functional>
#include <algorithm>
#include <vector>int main() {std::vector<int> vec = {1, 2, 3, 4, 5};int target = 3;// 使用equal_to查找目标值if(std::find_if(vec.begin(), vec.end(), std::bind2nd(std::equal_to<int>(), target)) != vec.end()) {std::cout << target << " is found in the vector." << std::endl;} else {std::cout << target << " is not found in the vector." << std::endl;}return 0;}
5.逻辑仿函数

逻辑仿函数用于组合或反转布尔值,它们也是在<functional>中定义的,包括:

  1. logical_and:对两个布尔值执行逻辑与操作。
  2. logical_or:对两个布尔值执行逻辑或操作。
  3. logical_not:对一个布尔值执行逻辑非操作。

逻辑仿函数示例

#include <iostream>
#include <functional>int main() {bool flag1 = true, flag2 = false;// 使用逻辑与if(std::logical_and<bool>()(flag1, flag2)) {std::cout << "Both flags are true." << std::endl;} else {std::cout << "Not both flags are true." << std::endl;}// 使用逻辑或if(std::logical_or<bool>()(flag1, flag2)) {std::cout << "At least one flag is true." << std::endl;}// 使用逻辑非std::cout << "Negation of flag2: " << std::logical_not<bool>()(flag2) << std::endl;return 0;
}

相关文章:

C++STL函数对象的应用

STL函数对象 文章目录 STL函数对象1.基本概念2.使用方法1. 简单函数对象示例2. 函数对象作为算法参数3. Lambda表达式作为函数对象 2.一元谓词和二元谓词1.一元谓词2.二元谓词3.总结 3.算术仿函数1.使用示例2.Lambda表达式的替代 4.关系仿函数5.逻辑仿函数 C中的函数对象&#…...

AJAX-day1:

注&#xff1a;文件布局&#xff1a; 一、AJAX的概念&#xff1a; AJAX是浏览器与服务器进行数据通信的技术 >把数据变活 二、AJAX的使用&#xff1a; 使用axios库&#xff0c;与服务器进行数据通信 基于XMLHttpRequest封装&#xff0c;代码简单 Vue,React项目使用 学习…...

昆虫学(书籍学习资料)

包括昆虫分类&#xff08;上下册&#xff09;、昆虫生态大图鉴等书籍资料。...

springboot + mybatis 多数据源切换

参考的b站博主写的 配置文件: spring:datasource:db1:jdbc-url: jdbc:mysql://localhost:3306/interview_database?useUnicodetrue&characterEncodingutf-8&useSSLfalseusername: rootpassword: 12345driver-class-name: com.mysql.cj.jdbc.Driverdb2:jdbc-url: jdbc…...

windows电脑网络重置后wifi列表消失怎么办?

我们的电脑网络偶尔会出现异常&#xff0c;我们通常会下意识选择网络诊断&#xff0c;运行完诊断后一般会让我们选择重置网络&#xff0c;然而&#xff0c;重置后wifi列表突然消失&#xff0c;无法愉快地上网了&#xff0c;找了一圈&#xff0c;都说是更改适配器选项&#xff0…...

Python + 在线 + 文生音,音转文(中文文本转为英文语音,语音转为中文文本)

开源模型 平台&#xff1a;https://huggingface.co/ars-语言转文本: pipeline("automatic-speech-recognition", model"openai/whisper-large-v3", device0 ) hf: https://huggingface.co/openai/whisper-large-v3 github: https://github.com/openai/wh…...

哏号分治,CF103D - Time to Raid Cowavans

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 103D - Time to Raid Cowavans 二、解题报告 1、思路分析 想了半天数据结构最终选择根号分治 我们考虑 大于 550 的公差直接暴力 小于550 的公差的所有询问&#xff0c;我们直接计算该公差后缀和&#xf…...

基于深度学习的图像背景剔除

在过去几年的机器学习领域&#xff0c;我一直想打造真正的机器学习产品。 几个月前&#xff0c;在参加了精彩的 Fast.AI 深度学习课程后&#xff0c;似乎一切皆有可能&#xff0c;我有机会&#xff1a;深度学习技术的进步使许多以前不可能实现的事情成为可能&#xff0c;而且开…...

Python使用(...)连接字符串

Python 字符串连接的灵活性。 使用括号来组织多行字符串时的自动拼接。 e e var_str g*3connect_str (fa{e}bcvar_strh )print(connect_str) print(type(connect_str)) 运行结果&#xff1a; aebcgggh <class str> 解释&#xff1a; 定义变量&#xff1a; e e:…...

鸿蒙:1.入门

概述 简介 鸿蒙操作系统&#xff08;HarmonyOS&#xff09;是华为公司发布的一款智能终端系统&#xff0c;是基于微内核的面向全场景的分布式操作系统。它致力于提供更加安全、高效、低延迟、低功耗的操作体验&#xff0c;可通过技术手段对应用程序和设备进行智能协同&#xf…...

【matlab】智能优化算法——求解目标函数

智能优化算法在求解目标函数方面发挥着重要作用&#xff0c;它通过迭代、筛选等方法来寻找目标函数的最优值&#xff08;极值&#xff09;。以下是关于智能优化算法求解目标函数的详细介绍&#xff1a; 一、智能优化算法概述 智能优化算法是一种搜索算法&#xff0c;旨在通过…...

不改代码,实现web.config或app.config的连接字符串加密解密

目的&#xff1a;加密字符串&#xff0c;防止明文显示。 好处&#xff1a;不用修改代码&#xff0c;微软自带功能&#xff0c;自动解密。 web.config 参考相关文章&#xff1a; Walkthrough: Encrypting Configuration Information Using Protected Configuration | Microso…...

Python创建MySQL数据库

一、使用Docker部署本地MySQL数据库 docker run --restartalways -p 3307:3306 --name mysql -e MYSOL_ROOT_PASSWORDlms123456 -d mysql:8.0.25 参数解析: 用户名:root 密码:lms123456 端口:3307 二、在Pycharm开发工具中配置连接MySQL数据库 三、安装zdppy_mysql pip inst…...

【C++】unordered系列容器的封装

你很自由 充满了无限可能 这是很棒的事 我衷心祈祷你可以相信自己 无悔地燃烧自己的人生 -- 东野圭吾 《解忧杂货店》 unordered系列的封装 1 unordered_map 和 unordered_set2 改造哈希桶2.1 模版参数2.2 加入迭代器 3 上层封装3.1 unordered_set3.2 unordered_map 4 面…...

matlab 超越椭圆函数图像绘制

matlab 超越椭圆函数图像绘制 超越椭圆函数图像绘制xy交叉项引入斜线负向斜线成分正向斜线成分 x^2 y^2 xy 1 &#xff08;负向&#xff09;绘制结果 x^2 y^2 - xy 1 &#xff08;正向&#xff09;绘制结果 超越椭圆函数图像绘制 xy交叉项引入斜线 相对于标准圆&#xf…...

本地文件同步上传到Gitee远程仓库

1、打开我们的项目所在文件夹 2、在项目文件夹【鼠标右击】弹出菜单&#xff0c;在【鼠标右击】弹出的菜单中&#xff0c;点击【Git Bash Here】&#xff0c;弹出运行窗口&#xff08;前提条件是已装好git环境&#xff09; 3、在命令窗口中输入&#xff1a;git init 4、在 Gite…...

RESTful Web 服务详解

RESTful Web 服务是一种基于 Representational State Transfer (REST) 架构风格的 Web 服务&#xff0c;它利用 HTTP 协议来传输数据&#xff0c;支持多种数据格式如 JSON 和 XML。在 Spring 框架中&#xff0c;通过简单配置和注解可以轻松实现 RESTful Web 服务。在本文中&…...

【ARMv8/v9 GIC 系列 5.3 -- 系统寄存器对中断的处理】

请阅读【ARM GICv3/v4 实战学习 】 文章目录 ARMv8/v9系统寄存器对中断的控制Group 0中断的寄存器Group 1中断的寄存器安全状态与中断分组中断处理过程中断确认处理代码中断完成处理代码ARMv8/v9系统寄存器对中断的控制 在ARM GIC 体系结构中,中断分组通过一系列系统寄存器进…...

MUNIK解读ISO26262--系统架构

功能安全之系统阶段-系统架构 我们来浅析下功能安全系统阶段重要话题——“系统架构” 目录概览&#xff1a; 系统架构的作用系统架构类型系统架构层级的相关安全机制梳理 1.系统架构的作用 架构的思维包括抽象思维、分层思维、结构化思维和演化思维。通过将复杂系统分解…...

STM32第十五课:LCD屏幕及应用

文章目录 需求一、LCD显示屏二、全屏图片三、数据显示1.显示欢迎词2.显示温湿度3.显示当前时间 四、需求实现代码 需求 1.在LCD屏上显示一张全屏图片。 2.在LCD屏上显示当前时间&#xff0c;温度&#xff0c;湿度。 一、LCD显示屏 液晶显示器&#xff0c;简称 LCD(Liquid Cry…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...

ZYNQ学习记录FPGA(二)Verilog语言

一、Verilog简介 1.1 HDL&#xff08;Hardware Description language&#xff09; 在解释HDL之前&#xff0c;先来了解一下数字系统设计的流程&#xff1a;逻辑设计 -> 电路实现 -> 系统验证。 逻辑设计又称前端&#xff0c;在这个过程中就需要用到HDL&#xff0c;正文…...

使用python进行图像处理—图像滤波(5)

图像滤波是图像处理中最基本和最重要的操作之一。它的目的是在空间域上修改图像的像素值&#xff0c;以达到平滑&#xff08;去噪&#xff09;、锐化、边缘检测等效果。滤波通常通过卷积操作实现。 5.1卷积(Convolution)原理 卷积是滤波的核心。它是一种数学运算&#xff0c;…...

2025 后端自学UNIAPP【项目实战:旅游项目】7、景点详情页面【完结】

1、获取景点详情的请求【my_api.js】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http(/login/getWXSessionKey, {code,avatar}); };//…...

claude3.7高阶玩法,生成系统架构图,国内直接使用

文章目录 零、前言一、操作指南操作指导 二、提示词模板三、实战图书管理系统通过4o模型生成系统描述通过claude3.7生成系统架构图svg代码转换成图片 在线考试系统通过4o模型生成系统描述通过claude3.7生成系统架构图svg代码转换成图片 四、感受 零、前言 现在很多AI大模型可以…...

学习英语。

1. 先自己翻译一遍&#xff08;葫芦背书法&#xff09; 结构 补充修饰 最核心的记忆 然后再修饰 2.意群之间翻译&#xff1a; 1.意群 对于两个意群合起来翻译 方法1就是着重某一 6.或者意群之间 核心词一个介词 于 对于 介词化修饰 3.句子之间关系 主句1 after句子2 那么句…...

Ntfs!ReadIndexBuffer函数分析之nt!CcGetVirtualAddress函数之nt!CcGetVacbMiss

第一部分&#xff1a; NtfsMapStream( IrpContext, Scb, LlBytesFromIndexBlocks( IndexBlock, Scb->ScbType.Index.IndexBlockByteShift ), Scb->ScbType.Index.BytesPerIndexBuffer, &am…...