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

C++之lambda匿名、using、typedef总结【全】(二百四十九)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

1.前言

本篇目的:理解C++之lambda匿名函数、typedef、using等用法

2.C++之lambda匿名、using、typedef介绍

1.lambda介绍

  • Lambda函数是一种匿名函数,可以在C++中使用。它提供了一种简洁的方式来定义和使用临时的函数对象。Lambda函数通过使用方便的语法来简化函数对象的创建过程,使代码更加简洁和易读。

Lambda函数的基本语法如下:

[capture list] (parameters) -> return_type { function_body }
  • Capture列表:指定Lambda函数所捕获的外部变量。它可以是值捕获(通过值进行拷贝)或引用捕获(通过引用进行访问)的方式。
  • 参数列表:指定Lambda函数的参数。
  • 返回类型:指定Lambda函数的返回类型(可以省略,编译器会自动推断)。
  • 函数体:实现Lambda函数的具体逻辑。

3.lambda匿名、using、typedef介绍

  1. Lambda匿名函数:
    Lambda函数是一种匿名函数,允许我们在需要函数对象的地方定义临时的、即时的函数逻辑。它的语法如下:
[capture list] (parameters) -> return_type { function_body }
  • Capture列表(可选): 指定Lambda函数所捕获的外部变量。
  • 参数列表: 指定Lambda函数的参数。
  • 返回类型(可选): 指定Lambda函数的返回类型。如果不指定,则编译器会自动推断。
  • 函数体: 实现Lambda函数的具体逻辑。

Lambda函数可以用于算法函数、STL容器的处理、回调函数等地方,可以使代码更加简洁和易读。

  1. using声明:
    Using声明在C++中用来引入一个特定的类型或命名空间,以便在当前作用域中使用。它的语法如下:
using name = type;

这里的name是我们定义的别名,type是需要引入的类型。

Using声明可以用来简化复杂的类型名称,或者引入命名空间中的类型。例如:

using IntVector = std::vector<int>;IntVector numbers = {1, 2, 3, 4, 5};

这里,我们使用了using声明引入了std::vector<int>类型的别名IntVector,从而将其简化为更易读的名称。

  1. typedef声明:
    Typedef声明也是用来引入一个特定的类型别名,以便在当前作用域中使用。它的语法如下:
typedef type name;

这里的type是我们需要引入的类型,name是我们定义的别名。

Typedef声明的作用和using声明类似,它也可以用来简化复杂的类型名称。例如:

typedef std::vector<int> IntVector;IntVector numbers = {1, 2, 3, 4, 5};

这里,我们使用了typedef声明将std::vector<int>类型定义为IntVector,从而使代码更加易读。

总结:
Lambda函数提供了一种简洁的方式来定义匿名函数,using声明和typedef声明提供了简化类型名称的能力。这些工具可以使代码更加清晰、易读和易于维护。

3.代码实例

v1.0 函数调用实例

#include <iostream>
#include <string>
#include <functional>typedef std::function<int(int x, int y)> Callback ;
using UCallback = std::function<int(int x, int y)> ;//v1.0
int call_add(std::function<int(int x, int y)> call){int a = 100, b=500;call(a, b);//传值a,b给调用者.return a+b;
}//v2.0: 与以上等同:使用typedef定义Callback类型别名定义
int call_add_01(Callback call){int a = 100, b=500;call(a, b);//传值a,b给调用者.return a+b;
}//v3.0: 与以上等同:使用using定义UCallback类型别名定义
int call_add_02(UCallback call){int a = 100, b=500;call(a, b);//传值a,b给调用者.return a+b;
}int main() {//v1.0:匿名lambda函数,无参数,无返回值.[](){printf("xxx----->%s(), line = %d\n",__FUNCTION__,__LINE__);}();//v2.0:匿名lambda函数,带string参数,无返回值.[](std::string content){printf("xxx----->%s(), line = %d, content = %s\n",__FUNCTION__,__LINE__,content.c_str());}("Hello Wolrd.");//v3.0:匿名lambda函数,带string和int类型参数,无返回值.std::string buf = "Hello, C++!";int year = 2023;[](std::string buf, int years){printf("xxx----->%s(), line = %d, buf = %s, years = %d\n",__FUNCTION__,__LINE__,buf.c_str(), years);}(buf, year);//v3.1: lambda带返回值int moth = [](std::string buf, int years){printf("xxx----->%s(), line = %d, buf = %s, years = %d\n",__FUNCTION__,__LINE__,buf.c_str(), years);int month = 10;return month;}(buf, year);printf("xxx----->%s(), line = %d, moth = %d\n",__FUNCTION__,__LINE__,moth);//4.0: 使用typedef创建别名类型Callback,然后调用回调函数.Callback add = [](int a, int b)->int {printf("xxx---------->%s(), line = %d, a = %d, b = %d\n",__FUNCTION__,__LINE__,a,b);return a + b;};printf("xxx----->%s(), line = %d, add = %d\n",__FUNCTION__,__LINE__,add(2, 3));//v5.0: 使用typedef定义回调函数类型别名int ret1 = call_add(add);printf("xxx----->%s(), line = %d, ret1 = %d\n",__FUNCTION__,__LINE__,ret1);//v6.0: 直接使用lambda匿名回调函数int ret2 = call_add([](int x, int y)->int{return x + y;});printf("xxx----->%s(), line = %d, ret2 = %d\n",__FUNCTION__,__LINE__,ret2);//v7.0: 使用typedef定义回调函数类型别名int ret3 = call_add_01(add);printf("xxx----->%s(), line = %d, ret3 = %d\n",__FUNCTION__,__LINE__,ret3);//v8.0: 使用using定义回调函数类型别名int ret4 = call_add_02(add);printf("xxx----->%s(), line = %d, ret4 = %d\n",__FUNCTION__,__LINE__,ret4);//v9.0: 直接使用lambda匿名回调函数int ret5 = call_add_02([](int x, int y)->int{return x + y;});printf("xxx----->%s(), line = %d, ret5 = %d\n",__FUNCTION__,__LINE__,ret5);return 0;
}

v2.0 类指针、引用、指针的引用实例01

#include <iostream>
#include <string>
#include <memory>
#include <functional>class TEST{
public:void log(){printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);}TEST(){printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);}TEST(std::shared_ptr<TEST> &test){printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);}
};//1.typedef定义:typedef 类型 别名.
typedef std::function<void(std::shared_ptr<TEST> &test)> Callback ;
//2.using定义:using 别名 = 类型.
using UCallback = std::function<void(std::shared_ptr<TEST> &test)> ;void callback_test(std::function<void(std::shared_ptr<TEST> &test)> func){std::shared_ptr<TEST> tt = std::make_shared<TEST>();func(tt);
}int main() {//v1.0: lambda匿名函数返回指针TEST*类型,无参数TEST *t1 = [&]()->TEST*{return new TEST;}();t1->log();//v1.1TEST *t12 = [&]()->TEST*{return new TEST;}();t12->log();//2.0: lambda匿名函数返回TEST类型指针对象,无参数TEST t2 = [&]()->TEST{return TEST{}; //TEST{}创建对象方式}();t2.log();//v2.1: TEST()创建对象方式TEST t21 = [&]()->TEST{return TEST();}();t21.log();//3.0: lambda匿名函数返回TEST类型指针对象,无返回值TEST *t3;[&](TEST *tr){tr = new TEST;}(t3);t3->log();//4.0: lambda匿名函数返回TEST类型指针的引用对象,无返回值TEST *t4;[&](TEST* &tr){//指针的引用tr = new TEST();}(t4);t4->log();//5.0: lambda匿名函数返回TEST类型shared_ptr指针对象,无返回值std::shared_ptr<TEST> t5;[&](std::shared_ptr<TEST> tr){//指向TEST类型shared_ptr指针对象tr = std::make_shared<TEST>();}(t5);t5->log();//6.0: lambda匿名函数返回TEST类型shared_ptr指针的引用对象,无返回值std::shared_ptr<TEST> t6;[&](std::shared_ptr<TEST> &tr){//指向TEST类型shared_ptr指针的引用的对象,即make_shared<TEST>()指针对象的别名.tr = std::make_shared<TEST>();}(t6);t6->log();//7.0: lambda匿名函数返回TEST类型shared_ptr指针的引用对象std::shared_ptr<TEST> t7;[&](std::shared_ptr<TEST> &tr)->std::shared_ptr<TEST> {//指向TEST类型shared_ptr指针的引用的对象,即make_shared<TEST>()指针对象的别名.//tr = std::make_shared<TEST>();return std::make_shared<TEST>(tr);}(t7);t7->log();//8.0: lambda匿名函数返回TEST类型shared_ptr指针的引用对象,有返回值和参数./*t8和t8.get()区别:t8是一个std::shared_ptr<TEST>类型的共享指针,指向一个TEST对象.t8.get(): 返回的是一个指向同一对象的原始指针.*/std::shared_ptr<TEST> t8;[&](void* tr) -> std::shared_ptr<TEST> {return std::make_shared<TEST>(static_cast<TEST*>(tr));}(t8.get());t8->log();//9.0std::shared_ptr<TEST> t10;callback_test([&](std::shared_ptr<TEST>& tr) -> void {t10 = tr;});t10->log();return 0;
}

v3.0 类指针、引用、指针的引用实例02

#include <iostream>
#include <string>
#include <memory>
#include <functional>class TEST{
public:void log(){printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);}TEST(){printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);}TEST(std::shared_ptr<TEST> &test){printf("xxx--------->%s(), line = %d\n",__FUNCTION__,__LINE__);}
};//1.typedef定义:typedef 类型 别名.
typedef std::function<void(std::shared_ptr<TEST> &test)> Callback ;
//2.using定义:using 别名 = 类型.
using UCallback = std::function<void(std::shared_ptr<TEST> &test)> ;void callback_test(std::function<void(std::shared_ptr<TEST> &test)> func){std::shared_ptr<TEST> tt = std::make_shared<TEST>();func(tt);
}std::shared_ptr<TEST> callback_ret(){//std::shared_ptr<TEST> tt = std::make_shared<TEST>();//return tt;return std::make_shared<TEST>();
}int main() {//v1.0std::shared_ptr<TEST> t1= callback_ret();t1->log();//v2.0std::shared_ptr<TEST> t2;callback_test([&](std::shared_ptr<TEST> &tr) -> void {t2 = tr;});t2->log();return 0;
}

C++中shared_ptr和shared_ptr::get()实现

template<typename T>
class shared_ptr {
public:explicit shared_ptr(T* ptr = nullptr) : ptr_(ptr), ref_count_(new int(1)) {}~shared_ptr() {if (--(*ref_count_) == 0) {delete ptr_;delete ref_count_;}}shared_ptr(const shared_ptr& other) : ptr_(other.ptr_), ref_count_(other.ref_count_) {++(*ref_count_);}shared_ptr& operator=(const shared_ptr& other) {if (this != &other) {if (--(*ref_count_) == 0) {delete ptr_;delete ref_count_;}ptr_ = other.ptr_;ref_count_ = other.ref_count_;++(*ref_count_);}return *this;}T* get() const {return ptr_;}private:T* ptr_;               // 指向所管理的对象的原始指针int* ref_count_;       // 引用计数,记录共享此对象的智能指针数量
};

shared_ptr类维护了一个指针ptr_和一个计数器ref_count_。每当有新的shared_ptr指向相同的对象时,ref_count_会递增。当没有shared_ptr指向该对象时,ref_count_会减少并在变为零时释放资源。

get()函数的实现非常简单,它只需返回私有成员ptr_,即所管理的对象原始指针。

相关文章:

C++之lambda匿名、using、typedef总结【全】(二百四十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…...

基于SpringBoot的个人博客系统

基于SpringBootVue的个人博客系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 系统公告 博客详情 后台发文 摘要 基于Spring Boot的个人博客系统是一种…...

javascript中的继承

基本术语 本文中&#xff0c;proto [[Prototype]] 原型链 基本思想&#xff1a; 构造函数生成的对象有一个指针&#xff08;proto&#xff09;指向构造函数的原型。如果将构造函数1的原型指向另一个构造函数2的实例&#xff0c;则构造函数1的实例__proto__.proto 指向了构…...

智能问答技术在百度搜索中的应用

作者 | Xiaodong 导读 本文主要介绍了智能问答技术在百度搜索中的应用。包括机器问答的发展历程、生成式问答、百度搜索智能问答应用。欢迎大家加入百度搜索团队&#xff0c;共同探索智能问答技术的发展方向&#xff0c;文末有简历投递方式。 全文6474字&#xff0c;预计阅读时…...

STM32F4X SDIO(一) SD卡介绍

STM32F4X SDIO&#xff08;一&#xff09; SD卡介绍 SD卡分类外观分类容量分类传输速度分类 在之前的章节中&#xff0c;讲过有关嵌入式的存储设备&#xff0c;有用I2C驱动的EEPROM、SPI驱动的FLASH和MCU内部的FLASH&#xff0c;这类存储设备的优点是操作简单&#xff0c;但是缺…...

10分钟了解JWT令牌 (JSON Web)

10分钟了解JSON Web令牌&#xff08;JWT&#xff09; JSON Web Token&#xff08;JWT&#xff09;是目前最流行的跨域身份验证解决方案。今天给大家介绍JWT的原理和用法。 1.跨域身份验证 Internet服务无法与用户身份验证分开。一般过程如下。 1.用户向服务器发送用户名和密码。…...

【经验总结】ECU系统休眠后通过诊断报文唤醒ECU且唤醒网络后快发NM报文

目录 前言 正文 1.CanNM状体机分析 2.ComM状态机分析 3.解决方案 4.总结 前言...

基于Android 10系统的ROC-RK3399-PC Pro源码编译

基于Android 10系统的ROC-RK3399-PC Pro源码编译 一、开发环境搭建二、下载Android 10 SDK三、编译Android 10 SDK ROC-RK3399-PC Pro资料下载处&#xff1a;https://www.t-firefly.com/doc/download/145.html一、开发环境搭建 Android 10 SDK的编译对PC机的要求不低&#xff…...

网络滤波器/网络滤波器/脉冲变压器要怎样进行测试,一般要测试哪些参数?

Hqst华强盛导读&#xff1a;网络滤波器/网络滤波器/脉冲变压器要怎样进行测试&#xff0c;一般要测试哪些参数&#xff1f;测试网络滤波器的测试方法和步骤如何&#xff0c;需用到哪些测试工具和仪器设备呢&#xff1f; 一&#xff0c;网络流量的监控和过滤能力测试&am…...

基于vue天气数据可视化平台

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…...

Go 语言常见的 ORM 框架

ORM&#xff08;Object-Relational Mapping&#xff09;是一种编程技术&#xff0c;用于将面向对象编程语言中的对象模型和关系数据库中的数据模型相互映射。ORM框架可以把数据操作从 SQL 语句中抽离出来&#xff0c;将关系型数据库中的表映射成对象&#xff0c;通过面向对象的…...

【错误解决方案】ModuleNotFoundError: No module named ‘cPickle‘

1. 错误提示 在python程序中试图导入一个名为cPickle的模块&#xff0c;但Python提示找不到这个模块。 错误提示&#xff1a;ModuleNotFoundError: No module named cPickle 2. 解决方案 实际上&#xff0c;cPickle是Python的pickle模块的一个C语言实现&#xff0c;通常用于…...

NodeJS14.18.0 安装,以及安装相应版本node-sass

安装了NVM, NodeJS 14.18.0 安装nvm 到c:\nvm目录 务必&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; nvm文档手册 - nvm是一个nodejs版本管理工具 - nvm中文网 编辑c:\nvm\settings.txt添加 node_mirror: CNPM Binar…...

cosover是什么?crossover23又是什么软件

cosover是篮球里的过人技巧。 1.crossover在篮球中的本意是交叉步和急速交叉步。crossover 是篮球术语&#xff0c;有胯下运球、双手交替运球&#xff0c;交叉步过人、急速大幅度变向等之意。 2.在NBA里是指包括胯下运球、变向、插花在内的过人的技巧。 NBA有很多著名的Cross…...

AR眼镜安卓主板,智能眼镜光机方案定制

AR智能眼镜是一项涉及广泛技术的创新产品&#xff0c;它需要考虑到光学、显示、功耗、散热、延迟、重量以及佩戴人体工学等多个方面的因素&#xff0c;每一个项目都是技术进步所需攻克的难题。 在本文中&#xff0c;我们将重点讨论AR眼镜的主板和光学方案。 首先是AR智能眼镜的…...

Qt中实现页面切换的两种方式

文章目录 方式一 &#xff1a;使用QStackedWidget讲解代码结构main.cpp完整代码运行结果&#xff1a; 方式二 &#xff1a;代码结构完整代码mainwindow.hnewmainwindow.hmain.cppmainwindow.cppnewmainwindow.cppmainwindow.uinewmainwindow.ui 效果 方式一 &#xff1a;使用QS…...

公司电脑如何限制安装软件

公司电脑如何限制安装软件 安企神终端管理系统下载使用 在企业环境中&#xff0c;电脑已经成为企业中必不可少的办公工具&#xff0c;确保员工的生产力和公司的信息安全是至关重要的。为了实现这一目标&#xff0c;公司可能会限制员工在某些情况下安装软件或者由管理员来为终…...

【C++】STL容器——list类的使用指南(含代码演示)(13)

前言 大家好吖&#xff0c;欢迎来到 YY 滴C系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; 目录 一、list 类——基本介绍二、list 类——…...

Table-GPT:让大语言模型理解表格数据

llm对文本指令非常有用&#xff0c;但是如果我们尝试向模型提供某种文本格式的表格数据和该表格上的问题&#xff0c;LLM更有可能产生不准确的响应。 在这篇文章中&#xff0c;我们将介绍微软发表的一篇研究论文&#xff0c;“Table-GPT: Table- tuning GPT for Diverse Table…...

基于单片机的温湿度和二氧化碳检测系统设计

目录 摘 要... 2 第一章 绪论... 5 1.1 研究课题背景... 5 1.2 国内外发展概况... 7 1.3 课题研究的目的... 8 1.4 课题的研究内容及章节安排... 9 第二章 二氧化碳和温湿度检测系统控制系统的设计方案... 11 2.1 设计任务及要求... 11 2.2 二氧化碳和…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...