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

【STL十四】函数对象(function object)_仿函数(functor)——lambda表达式

【STL十四】函数对象(function object)_仿函数(functor)——lambda表达式

  • 一、函数对象(function object)
  • 二、函数对象优点
  • 三、分类
  • 四、头文件
  • 五、用户定义函数对象demo
  • 六、std::内建函数对象
    • 1、 算术运算函数对象
    • 2、比较
    • 3、逻辑运算
    • 4、位运算
  • 七、lambda表达式
    • 1、简介
    • 2、作用
    • 3、定义
    • 4、最简单的demo
    • 5、标准用法
    • 6、变量捕获(capture clause)

一、函数对象(function object)

  • 定义:定义了一个operator()的对象,就叫函数对象(function object)。
  • 函数对象又被叫做仿函数(functor)。

注意:

  • 函数对象是一个类(or结构体、模板类),不是一个函数。
  • 函数对象重载“()”操作符,使得类可以像函数那样调用。

安装参数分
如果函数对象,有一个参数,叫一元函数对象。
如果函数对象,有二个参数,叫二元函数对象。
如果函数对象,有三个参数,叫多元函数对象。

二、函数对象优点

  • 函数对象通常不定义构造函数和析构函数,所以在构造和析构不会发生问题
  • 函数对象可以有自己的状态;(超出了普通函数的概念)
  • 模板函数对象使得函数对象具有通用性。

三、分类

  • 用户定义函数对象
  • std::内置函数对象
  • lambda表达式

四、头文件

  • 用户自己定义的函数无头文件,
  • std内建函数对象
    头文件如下
// 内置函数对象
#include<functional>

五、用户定义函数对象demo

  • Print就是函数对象
  • Print()(“HELLO WORLD”);//匿名函数对象
#include <iostream>
//
using namespace std;class Print
{
public:void operator()(const char str[]){cout << str << endl;}
};int main() {Print ob;ob("hello world");Print()("HELLO WORLD");//匿名函数对象}

输出

hello world
HELLO WORLD

  • 函数对象可以有自己的状态?
    demo
#include <iostream>
//#include<functional>
using namespace std;class Print
{
public:void operator()(const char str[]){cout << str << endl;m_sum++;}int m_sum = 0;
};int main() {Print ob;ob("hello world");ob("hello jx");cout << ob.m_sum << endl;}

输出

hello world
hello jx
2

  • 当然以上你可以写成模板,or同时重载int类型的,都是可以的

    • 重载int类型的
#include <iostream>
//#include<functional>
using namespace std;struct Print
{
public:void operator()(const char str[]){cout << str << endl;}void operator()(int num){cout << num << endl;}
};int main() {Print ob;ob("hello world");Print()("HELLO WORLD");ob(110);}
  • 模板函数对象使得含对象具有通用性?
    • 模板
#include <iostream>
#include<string>
using namespace std;template<typename T>
class Print
{
public:void operator()(T temp){cout << temp << endl;m_sum++;}int m_sum = 0;
};int main() {Print<string> ob;ob("hello world");ob("hello jx");cout << ob.m_sum << endl;Print<int> ob2;ob2(123);ob2(123);
}

输出

hello world
hello jx
2
123
123

六、std::内建函数对象

  • stl内建了一些函数对象,分为算术运算、比较、逻辑运算、位运算;
  • 其实,这些内建函数对象,都是配合容器和算法使用的,但是我们还没有讲解郭算法,所以做个不设计算法的简单的demo.

1、 算术运算函数对象

  • 1.1、分类
    在这里插入图片描述
  • 1.2、demo
#include <iostream>
#include<functional>
using namespace std;int main() {std::plus<int>  add;cout << "add(2, 3) = " << add(2, 3) << endl; //2+3 = 5std::minus<int> sub;cout << "sub(2, 3) = " << sub(2, 3) << endl; //2-3 = -1std::multiplies<int> mul;cout << "mul(2, 3) = " << mul(2, 3) << endl; //2*3 = 6std::divides<int> div;cout << "div(2, 3) = " << div(2, 3) << endl; //2/3 = 0std::modulus<int> mod;cout << "mod(2, 3) = " << mod(2, 3) << endl; //2%3 = 2std::negate<int> neg;cout << "neg(2) = " << neg(2) << endl; //neg(2) = -2 }

输出

add(2, 3) = 5
sub(2, 3) = -1
mul(2, 3) = 6
div(2, 3) = 0
mod(2, 3) = 2
neg(2) = -2

2、比较

  • 2.1、分类
    在这里插入图片描述
  • 2.2、demo
#include <iostream>
#include<functional>
using namespace std;int main() {std::equal_to<int> ob1;cout << "ob1(1, 2) = " << ob1(1, 2) << endl;std::not_equal_to<int> ob2;cout << "ob2(1, 2) = " << ob2(1, 2) << endl;std::greater<int> ob3;cout << "ob3(1, 2) = " << ob3(1, 2) << endl;std::less<int> ob4;cout << "ob4(1, 2) = " << ob4(1, 2) << endl;std::greater_equal<int> ob5;cout << "ob5(1, 2) = " << ob5(1, 2) << endl;std::less_equal<int> ob6;cout << "ob6(1, 2) = " << ob6(1, 2) << endl;
}

输出

ob1(1, 2) = 0
ob2(1, 2) = 1
ob3(1, 2) = 0
ob4(1, 2) = 1
ob5(1, 2) = 0
ob6(1, 2) = 1

3、逻辑运算

  • 3.1、分类
    在这里插入图片描述
  • 3.2、demo
#include <iostream>
#include<functional>
using namespace std;int main() {std::logical_and<bool> l_and;cout << "l_and(1, 0) = " << l_and(1, 0) << endl;std::logical_or<int> l_or;cout << "l_or(1, 0) = " << l_or(1, 0) << endl; std::logical_not<int> l_not;cout << "l_not(2) = " << l_not(2) << endl; 
}

输出

l_and(1, 0) = 0
l_or(1, 0) = 1
l_not(2) = 0

4、位运算

  • 4.1、分类
    在这里插入图片描述
    • demo
  • 1、“与” 运算(&):只有两个位都是1的时候结果才是1,否则是0;如1&1=1,1&0=0,0&1=0,0&0=0
  • 2、“或” 运算(|):只要有一个是1,结果就是1。如:1|0=1,0|1=1,1|1=1,0|0=0
  • 3、“异或” 运算(^):相同为0,不同为1;0|0=0,0|1=1,1|0=1,1|1=0
  • 4、取反运算(~):就是0=1,1=0
#include <iostream>
#include<functional>
using namespace std;int main() {std::bit_and<int> b_and;cout << "b_and(1, 2) = " << b_and(1, 2) << endl;std::bit_or<int> b_or;cout << "b_or(1, 2) = " << b_or(1, 2) << endl;std::bit_xor<int> b_xor;cout << "b_xor(2,3) = " << b_xor(2,3) << endl;std::bit_not<bool> b_not;cout << "b_not(1) = " << b_not(1) << endl;
}

输出

b_and(1, 2) = 0
b_or(1, 2) = 3
b_xor(2,3) = 1
b_not(1) = 1

bit_not有问题,因为bool的取反,应该是0,但是输出是1,原因未知;

七、lambda表达式

使用 STL 时,往往会大量用到函数对象,为此要编写很多函数对象类。有的函数对象类只用来定义了一个对象,而且这个对象也只使用了一次,编写这样的函数对象类就有点浪费。
而且,定义函数对象类的地方和使用函数对象的地方可能相隔较远,看到函数对象,想要查看其 operator() 成员函数到底是做什么的也会比较麻烦。

  • 对于只使用一次的函数对象类,能否直接在使用它的地方定义呢?Lambda 表达式能够解决这个问题。使用 Lambda 表达式可以减少程序中函数对象类的数量,使得程序更加优雅。

1、简介

  • lambda expressions = lambda表达式(也叫闭包——Colsure)
  • lambda表达式也是匿名函数对象
  • lambda表达式也是一种仿函数、

2、作用

  • 很方便的定义函数、并被别的函数调用。

3、定义

Lambda 表达式的定义形式如下:

[]中括号里面是一下捕获变量,或者为空。

[捕获变量] (参数表) -> 返回值类型
{函数主体
}auto f=[](int a, int b) ->int
{
return a+b;
};

“捕获变量”可以是=或&,表示{}中用到的、定义在{}外面的变量在{}中是否允许被改变。=表示不允许,&表示允许。当然,在{}中也可以不使用定义在外面的变量。“-> 返回值类型”可以省略。

4、最简单的demo

#include <iostream>
#include<vector>
#include<functional>
using namespace std;int main() {auto f = [](int a, int b){return a < b;};cout << f(2, 3);
}

输出

1

5、标准用法

#include <iostream>
#include<vector>
#include<functional>
using namespace std;int main() {// 定义lambda表达式,不使用变量捕获auto f = [](int a, int b) ->int{return a + b;};cout << f(1, 2) << endl;
}

输出

3

6、变量捕获(capture clause)

#include <iostream>
#include<vector>
#include<functional>
using namespace std;int main() {int M = 10;int N = 3;auto f = [&M, N](int a) ->int{M = 20;return N*a;};cout << f(3) << endl;cout << M << endl;
}

输出

9
20

  • 变量捕获:就是方括号中的部分,让我们的匿名函数可以访问、甚至修改函数外部的变量。
  • 如果是空,表示不捕获任何变量。
  • [&M]——如果变量前有引用&,则是按引用捕获——可以修改外围变量的值。
  • [M]——如果变量前没引用&,则是按值捕获——不可以修改外围变量的值。
  • [&]——只写引用,按照引用捕获所有的封闭范围中的变量;
  • [=]——只写等号,所有变量都按值捕获;
  • [&, = M]——单独制定一些变量按照值捕获,其他变量按照引用捕获;
  • [this]——如果在某个class中使用匿名函数,可以使用this捕获当前实例的指针。
  • c++17后还可以使用[*this]按值捕获该实例。
  • c++14后,可以在捕获语句中定义新的变量,并初始化。(这些变量无需出现在匿名函数外围环境中)
auto f = [&M, N, k=5](int a) ->int{M = 20;return N*a*k;};
  • c++14后,参数列表支持auto类型
[](auto a, auto b){return a+b;}

参考:
1、C++ STL 容器库 中文文档
2、STL教程:C++ STL快速入门
3、https://www.apiref.com/cpp-zh/cpp/header.html
4、https://en.cppreference.com/w/cpp/container
5、哔哩哔哩_HexUp_清晰易懂,现代C++最好用特性之一:Lambda表达式用法详解
6、WIKI教程_C ++标准库_C++ Library - <iterator>

相关文章:

【STL十四】函数对象(function object)_仿函数(functor)——lambda表达式

【STL十四】函数对象&#xff08;function object&#xff09;_仿函数&#xff08;functor&#xff09;——lambda表达式 一、函数对象&#xff08;function object&#xff09;二、函数对象优点三、分类四、头文件五、用户定义函数对象demo六、std::内建函数对象1、 算术运算函…...

如何写出高质量的前端代码

写出高质量的前端代码是每个前端开发人员的追求。在一个复杂的项目中&#xff0c;代码质量对于项目的可维护性、可扩展性和可读性都有很大的影响。本文将介绍一些如何写出高质量前端代码的技巧和最佳实践。 一、注重代码结构和组织 1.1 遵循一致的命名规范 命名规范是编写高…...

YOLOv7如何提高目标检测的速度和精度,基于优化算法提高目标检测速度

目录 一、学习率调度二、权重衰减和正则化三、梯度累积和分布式训练1、梯度累积2、分布式训练 四、自适应梯度裁剪 大家好&#xff0c;我是哪吒。 上一篇介绍了YOLOv7如何提高目标检测的速度和精度&#xff0c;基于模型结构提高目标检测速度&#xff0c;本篇介绍一下基于优化算…...

CentOS 7中安装配置Nginx的教程指南

1. 安装Nginx 在终端中执行以下命令以安装Nginx&#xff1a; sudo yum install epel-release sudo yum install nginx安装完成后的 Nginx 内容通常会被安装在以下目录下&#xff1a; /etc/nginx: 该目录包含 Nginx 的配置文件&#xff0c;包括 nginx.conf 和 conf.d 目录下的…...

Vicuna- 一个类 ChatGPT开源 模型

Meta 开源 LLaMA(大羊驼)系列模型为起点,研究人员逐渐研发出基于LLaMA的Alpaca(羊驼)、Alpaca-Lora、Luotuo(骆驼)等轻量级类 ChatGPT 模型并开源。 google提出了一个新的模型:Vicuna(小羊驼)。该模型基于LLaMA,参数量13B。Vicuna-13B 通过微调 LLaMA 实现了高性能…...

5.1 数值微分

学习目标&#xff1a; 作为数值分析的基础内容&#xff0c;我建议你可以采取以下步骤来学习数值微分&#xff1a; 掌握微积分基础&#xff1a;数值微分是微积分中的一个分支&#xff0c;需要先掌握微积分基础知识&#xff0c;包括导数、极限、微分等。 学习数值微分的概念和方…...

云计算服务安全评估办法

云计算服务安全评估办法 2019-07-22 14:46 来源&#xff1a; 网信办网站【字体&#xff1a;大 中 小】打印 国家互联网信息办公室 国家发展和改革委员会 工业和信息化部 财政部关于发布《云计算服务安全评估办法》的公告 2019年 第2号 为提高党政机关、关键信息基础设施运营者…...

laravel5.6.* + vue2 创建后台

本地已经安装好了composer 1.新建 Laravel5.6.*项目 composer create-project --prefer-dist laravel/laravel laravel5vue2demo 5.6.* 2. cd laravel5vue2demo 3. npm install /routes/web.php 路由文件中, 修改 Route::get(/, function () {return view(index); });新建…...

Python自动化sql注入:布尔盲注

在sql注入时&#xff0c;使用python脚本可以大大提高注入效率&#xff0c;这里演示一下编写python脚本实现布尔盲注的基本流程&#xff1a; 演示靶场&#xff1a;sqli-labs 布尔盲注 特点&#xff1a;没有回显没有报错&#xff0c;但根据sql语句正常与否返回不同结果&#x…...

Microsoft Defender for Office 365部署方案

目录 前言 一、Microsoft Defender for Office 365 部署架构 1、部署环境 2、Microsoft Defender for Office 365 核心服务...

字节岗位薪酬体系曝光,看完感叹:不服真不行

曾经的互联网是PC的时代&#xff0c;随着智能手机的普及&#xff0c;移动互联网开始飞速崛起。而字节跳动抓住了这波机遇&#xff0c;2015年&#xff0c;字节跳动全面加码短视频&#xff0c;从那以后&#xff0c;抖音成为了字节跳动用户、收入和估值的最大增长引擎。 自从字节…...

华为OD机试-高性能AI处理器-2022Q4 A卷-Py/Java/JS

某公司研发了一款高性能AI处理器。每台物理设备具备8颗AI处理器&#xff0c;编号分别为0、1、2、3、4、5、6、7。 编号0-3的处理器处于同一个链路中&#xff0c;编号4-7的处理器处于另外一个链路中&#xff0c;不同链路中的处理器不能通信。 现给定服务器可用的处理器编号数组…...

Vue - 实现垂直菜单分类栏目,鼠标移入后右侧出现悬浮二级菜单容器效果(完整示例源码,详细代码注释,一键复制开箱即用)

前言 网上的教程都太乱了,各种杂乱无注释代码、图片资源丢失、一堆样式代码,根本无法改造后应用到自己的项目中。 本文实现了 在 Vue / Nuxt 项目中,垂直分类菜单项,当用户鼠标移入菜单后,右侧自动出现二级分类悬浮容器盒子效果, 您可以直接复制源码,然后按照您的需求再…...

NVM-无缝切换Node版本

NVM-无缝切换Node版本 如果未使用nvm之前已经下载了node&#xff0c;并且配置了环境变量,那么此时删除这些配置(Node的环境以及Node软件),使用nvm是为了在某些项目中使用低版本的node NVM下载 进入github的nvm readme&#xff1a; https://github.com/coreybutler/nvm-windows…...

CCF-CSP真题《202303-1 田地丈量》思路+python,c++满分题解

想查看其他题的真题及题解的同学可以前往查看&#xff1a;CCF-CSP真题附题解大全 试题编号&#xff1a;202303-1试题名称&#xff1a;田地丈量时间限制&#xff1a;1.0s内存限制&#xff1a;512.0MB问题描述&#xff1a; 问题描述 西西艾弗岛上散落着 n 块田地。每块田地可视为…...

Autosar-软件架构

文章目录 一、Autosar软件架构分层图二、应用层三、RTE层四、BSW层1、微控制器抽象层2、ECU抽象层I/O硬件抽象COM硬件抽象Memory硬件抽象Onboard Device Abstraction3、复杂驱动层4、服务层系统服务通信服务CAN一、Autosar软件架构分层图 架构分层是实现软硬件分离的关键,它也…...

8年测开年薪30W,为什么从开发转型为测试?谈谈这些年的心路历程……

谈谈我的以前&#xff0c;从毕业以来从事过两个多月的Oracle开发后转型为软件测试&#xff0c;到现在已近过去8年成长为一个测试开发工程师&#xff0c;总结一下之间的心路历程&#xff0c;希望能给徘徊在开发和测试之前的同学一点小小参考。 一、测试之路伏笔 上学偷懒&#…...

滑动奇异频谱分析:数据驱动的非平稳信号分解工具(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

updateByPrimaryKey和updateByPrimaryKeySelective的区别

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl MyBatis Generator概述 MyBatis Generator是一个专门为MyBatis框架使用者定制的代码生成器&#xff0c;它可以快速的根据表生成对应的映射文件、接口文件、POJO。而且&#…...

【ARM Coresight 4 - Rom Table 介紹】

文章目录 1.1 ROM Table1.1.1 Entry 寄存器 1.2 ROM Table 例子 1.1 ROM Table 在一个SoC中&#xff0c;有多个Coresight 组件&#xff0c;但是软件怎么去识别这些 Coresight 组件&#xff0c;去获取这些Coresight 组件的信息了&#xff1f;这个时候&#xff0c;就需要靠 Core…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...