C++学习笔记(三十五):c++ 函数指针及lambda表达式

news2025/1/12 3:05:40

本节介绍c++函数指针。在一些源码中经常能看到c++函数指针,但之前一直觉着这一块比较复杂,就一直没去仔细研究,终于有时间去仔细研究这一块内容了。

  • c风格的函数指针
  • 函数指针是指将一个函数赋值给一个变量的方法,可以将函数作为一个参数传递给另一个函数,简单的使用示例如下
  • #include <iostream>
    
    void PrintMessage()
    {
    	std::cout << "Hello World!" << std::endl;
    }
    
    int main()
    {
    	//一般情况下调用函数的方式
    	//PrintMessage();
    
    	//函数指针
    	//取一个函数的地址赋值给一个变量
    	auto function = PrintMessage;  //不加()
    	//函数就是cpu指令,当编译完成代码后,函数处在二进制文件的某个地方
    	//赋值给一个变量后可以向之前调用函数一样调用
    	function();
    	function(); //打印 "Hello World!"
    
    	std::cin.get();
    }
  • 上述示例中是通过auto来接收,接下来看一下PrintMessage具体的返回值类型。
  • #include <iostream>
    
    void PrintMessage()
    {
    	std::cout << "Hello World!" << std::endl;
    }
    
    int main()
    {
    	//一般情况下调用函数的方式
    	//PrintMessage();
    
    	//函数指针
    	//取一个函数的地址赋值给一个变量
    	auto function = PrintMessage;  //不加()
    	//函数就是cpu指令,当编译完成代码后,函数处在二进制文件的某个地方
    	//赋值给一个变量后可以向之前调用函数一样调用
    	function();
    	function(); //打印 "Hello World!"
    
    	//实际PrintMessage返回的类型是void(*function)()
    	//实际的类型是void(*)(),最后一个括号里面的放的是函数的参数类型,function是我们给这个返回类型起的名字
    	void(*pcop)();
    	pcop = PrintMessage;
    	pcop();//打印 "Hello World!"
    
    	//上述的void(*pcop)()可以使用typedef,将别名写在如下位置,看起来可能有点奇怪,但确实是这样的
    	typedef void(*testFunctionPoint)();
    
    	testFunctionPoint heiheihei = PrintMessage;
    	heiheihei();//打印 "Hello World!"
    
    	std::cin.get();
    }
  • 接下来展示函数指针的函数包含参数的示例
  • #include <iostream>
    
    void PrintMessage(int a)
    {
    	std::cout << "Hello World! " << a <<std::endl;
    }
    
    int main()
    {
    	//一般情况下调用函数的方式
    	//PrintMessage();
    
    	//函数指针
    	//取一个函数的地址赋值给一个变量
    	auto function = PrintMessage;  //不加()
    	//函数就是cpu指令,当编译完成代码后,函数处在二进制文件的某个地方
    	//赋值给一个变量后可以向之前调用函数一样调用
    	function(1);
    	function(2); //打印 "Hello World!"
    
    	//实际PrintMessage返回的类型是void(*function)()
    	//实际的类型是void(*)(),最后一个括号里面的放的是函数的参数类型,function是我们给这个返回类型起的名字
    	void(*pcop)(int);
    	pcop = PrintMessage;
    	pcop(5);//打印 "Hello World!"
    
    	//上述的void(*pcop)()可以使用typedef,将别名写在如下位置,看起来可能有点奇怪,但确实是这样的
    	typedef void(*testFunctionPoint)(int);
    
    	testFunctionPoint heiheihei = PrintMessage;
    	heiheihei(6);//打印 "Hello World!"
    
    	std::cin.get();
    }
  • 上述描述的都是函数指针的原理,接下来大概展示函数指针的使用场景。
  • #include <iostream>
    #include <vector>
    void PrintValue(int value)
    {
    	std::cout << value << std::endl;
    }
    
    void ForEach(const std::vector<int>& values, void(*func)(int))
    {
    	for (int value:values)
    	{
    		func(value);
    	}
    }
    
    int main()
    {
    	std::vector<int> values = {1,4,6,7,9};
    	//创建一个函数,迭代遍历values中的所有元素,并将值进行打印
    	ForEach(values, PrintValue);
    
    	std::cin.get();
    }
  • c++lambda表达式
  • lambda表达式是指用一种匿名函数的创建函数,用这种方式创建函数不需要实际创建一个函数。只要有一个函数指针,都可以使用lambda。接下来通过代码展示lambda。
  • 上述的代码展示的是用lambda替换上节所讲述的PrintValue函数指针。()中传入的是lambda的{}中所需的参数,上述的func(value)实际上调用就是[](int value){std::cout << value << std::endl;}。
  • 接下来事例展示将一个函数传递给一个API,以便在未来的某个时间,可以为我们调用这个函数,现在不能掉用该函数,因为函数所需要的数据还为准备好,所以需要延迟调用。lambda可以很好的实现上述需求,代码实现如下:
  • []里面放的是lambda的捕获,当需要将外部的变量传入lambda{}中时用到。
  • #include <iostream>
    #include <vector>
    #include <functional>
    
    void ForEach(std::vector<int> vlaues ,const std::function<void(int)>& func)
    {
        for(int value:vlaues)
            func(value);
    }
    
    int main()
    {
        std::vector<int> values = {2,5,7,9,4};
        int a = 10;
        //想要在lambda中调用main函数的a变量,直接调用会报错
        //可以通过[=]值传递进行调用,也可以通过[&]传递进行调用
        //此时ForEach中的参数如果是原始函数指针就会报错,需要改成function
        auto lambda = [=](int value){std::cout << value << a << std::endl;};
        ForEach(values, lambda);
        
    }
    
  • std::find_if,迭代器查找值
  • #include <iostream>
    #include <vector>
    #include <functional>
    #include <algorithm>
    
    void ForEach(std::vector<int> vlaues ,const std::function<void(int)>& func)
    {
        for(int value:vlaues)
            func(value);
    }
    
    int main()
    {
        std::vector<int> values = {2,5,7,9,4};
        //用find_if查找vector中第一个比3大的元素
        auto it = std::find_if(values.begin(),values.end(),[](int value){return value>3;} );
        std::cout << *it << std::endl;
        int a = 10;
        //想要在lambda中调用main函数的a变量,直接调用会报错
        //可以通过[=]值传递进行调用,也可以通过[&]传递进行调用
        //此时ForEach中的参数如果是原始函数指针就会报错,需要改成function
        auto lambda = [=](int value){std::cout << value << a << std::endl;};
        ForEach(values, lambda);
        
    }
    

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

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

相关文章

基础_函数_流程函数

流程函数也是很常用的一类函数&#xff0c;可以在SQL语句中实现条件筛选&#xff0c;从而提高语句效率.

一天一个设计模式---桥接模式

概念 桥接器模式是一种结构型设计模式&#xff0c;旨在将抽象部分与实现部分分离&#xff0c;使它们可以独立变化而不相互影响。桥接器模式通过创建一个桥接接口&#xff0c;连接抽象和实现&#xff0c;从而使两者可以独立演化。 具体内容 桥接器模式通常包括以下几个要素&a…

文件夹重命名方法:英文文件夹名批量翻译成中文,高效管理文件夹

随着全球化的发展&#xff0c;经常要处理英文文件夹名的文件管理任务。要将这些英文文件夹名翻译成中文。如果一个个手动翻译和重命名不仅效率低下&#xff0c;还容易出错。下面一起看云炫文件管理器如何批量翻译重命名英文文件夹的方法&#xff0c;提高文件管理的效率。 文件…

Vue 中修改 Element 组件的 下拉菜单(Dropdown) 的样式

Vue 中修改 Element 组件的 下拉菜单(Dropdown) 的样式 今天在项目中碰到一个 UI 改造的需求&#xff0c;需要根据设计图把页面升级成 UI 设计师提供的设计图样式。 到最后页面改造完了&#xff0c;但是 UI 提供的下拉菜单样式全部是黑色半透明的&#xff0c;只能硬着头皮改了。…

面试算法115:重建序列

题目 长度为n的数组org是数字1&#xff5e;n的一个排列&#xff0c;seqs是若干序列&#xff0c;请判断数组org是否为可以由seqs重建的唯一序列。重建的序列是指seqs所有序列的最短公共超序列&#xff0c;即seqs中的任意序列都是该序列的子序列。 例如&#xff0c;如果数组org为…

语义解析:如何基于SQL去实现自然语言与机器智能连接的桥梁

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 &#x1f4ab;个人格言:"没有罗马,那就自己创造罗马~" 目录 语义解析 定义 作用 语义解析的应用场景 场景一&#xff1a; 场景二&#xff1a; 总结语…

Type-C PD充电器受电端sink诱骗取电汇总:小家电应用5V9V12V15V20V28V

小家电产品、美容产品、电动产品等升级采用Type-C接口&#xff0c;在Type-C接口上使用Type-C取电芯片&#xff0c;即可使用快速充电器的5V、9V、12V、15V、20V供电&#xff0c;无需再配充电器&#xff0c;各类品牌的充电器都可以支持。目前充电器常见的USB-PD功率为&#xff1a…

GPU测试相关命令

nvitopnvtopls -l /proc/1666855查找ip curl ip.sb curl myip.ipip.net

java项目之基于协同过滤算法的图书推荐系统(ssm)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的基于协同过滤算法的图书推荐系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 管理员功能需求…

计算机毕业设计------SSH宿舍管理系统

项目介绍 本项目分为三种角色&#xff1a;系统管理员、楼宇管理员、学生&#xff1b; 系统管理员主要功能如下&#xff1a; 楼宇管理员管理、学生管理、楼宇管理、宿舍管理、学生入住登记、学生寝室调换、学生迁出登记、学生缺勤记录、修改密码、退出登录 楼宇管理员主要功能…

qt初入门3:文件,目录,临时文件,监视相关demo

参考qt的书籍demo&#xff0c;做练习 目录和文件相关操作&#xff1a; QCoreApplication类 主要处理获取app所在目录&#xff0c;路径&#xff0c;app名称&#xff0c;lib库路径等。 QFile类 主要实现文件拷贝&#xff0c;校验存在&#xff0c;删除&#xff0c;重命名&#xf…

【OpenCV学习笔记04】- 绘图功能

这是对于 OpenCV 官方文档的 GUI 功能的学习笔记。学习笔记中会记录官方给出的例子&#xff0c;也会给出自己根据官方的例子完成的更改代码&#xff0c;同样彩蛋的实现也会结合多个知识点一起实现一些小功能&#xff0c;来帮助我们对学会的知识点进行结合应用。 如果有喜欢我笔…

如何使用宝塔面板部署Inis博客并实现无公网ip环境远程访问

文章目录 前言1. Inis博客网站搭建1.1. Inis博客网站下载和安装1.2 Inis博客网站测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;2.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 3. 公网访问测试总…

正则表达式、文件访问(Python实现)

一、主要目的&#xff1a; 1.了解正则表达式的基本概念和处理过程。 2.掌握使用正则表达式模块 Re 进行字符串处理的方法。 3.了解文件的基本概念和类型。 4.掌握在 Python 中访问文本文件的方法和步骤。 5.熟悉在 Python 中访问二进制文件的方法和步骤。 二、主要内容和结…

.NET开源、强大的Web报表统计系统

前言 今天分享一个.NET开源、强大的Web报表统计系统&#xff1a;CellReport。 项目官方介绍 CellReport 诞生的初衷是为了解决日常快速制作统计报表的需要。 CellReport 是一个为复杂统计报表为核心目标的制作、运行工具。你可以使用数据库、excel文件、api服务、已有报表等为…

【C++期末】酒店住宿信息管理系统(含easyX)

诚接计算机专业编程作业(C语言、C、Python、Java、HTML、JavaScript、Vue等)&#xff0c;如有需要请私信我&#xff0c;或者加我的企鹅号&#xff1a;1404293476 本文资源&#xff1a;https://download.csdn.net/download/weixin_47040861/88725363 目录 1.题目要求 2.实现效…

linux中出现不在 sudoers 文件中。此事将被报告的解决方法

出现如下提示gaokaoli 出现不在 sudoers 文件中。此事将被报告 一般是该用户 权限不够 既然知道权限不够可以添加到root用户组&#xff0c;获取权限即可 通过命令行添加到权限&#xff0c;发现还是不行 sudo usermod -g root gaokaoli 那就直接在配置文件中修改 通过执行vi…

需求跟踪矩阵的作用

需求跟踪矩阵对于嵌入式系统的整个生命周期至关重要。这种矩阵能够帮助确保产品的安全性并满足预设的质量标准。对于医疗、技术和工程等领域来说&#xff0c;需求追溯矩阵尤其关键。实际上&#xff0c;任何设定了目标和标准、并希望维护这些目标和标准的企业都能从这个经过实践…

ChatGPT提示词的高级技巧——解锁AI交互新境界

大家好我是在看&#xff0c;记录普通人学习探索AI之路。 这一讲我来介绍几种提示词的高级使用技巧。 1.拆解问题 对于一个一次性很难完整回答的大问题&#xff0c;我们可以将其拆解成若干子问题&#xff0c;再将这些问题逐步输入。 我们来看下面的例子&#xff1a; 2.迭代改…

Rough.js:创建手绘、草图外观的图形

Rough.js 是一个小型的(<9kB gzipped)图形库&#xff0c;它可以让你以草图、手绘风格进行绘制。 该库定义了绘制直线、曲线、圆弧、多边形、圆和椭圆的基元。它还支持绘制 SVG 路径。 Rough.js 可以同时处理 Canvas 和 SVG。 安装 从npm安装&#xff1a; npm install --s…