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

news2024/12/23 8:52:31

简介: 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.1
  TEST *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.0
  std::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.0
  std::shared_ptr<TEST> t1= callback_ret();
  t1->log();

  //v2.0
  std::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_,即所管理的对象原始指针。

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

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

相关文章

【图像分类】基于计算机视觉的坑洼道路检测和识别(ResNet网络,附代码和数据集)

写在前面: 首先感谢兄弟们的关注和订阅,让我有创作的动力,在创作过程我会尽最大能力,保证作品的质量,如果有问题,可以私信我,让我们携手共进,共创辉煌。 本篇博文,我们将使用PyTorch深度学习框架搭建ResNet实现钢轨缺陷识别,附完整的项目代码和数据集,可以说是全网…

BaiChuan-QWen

QWen Tokenizer 选择byte pair encoding (BPE)作为分词方法vacabulary在中文上做了增强&#xff0c;验证增加vocabulary的规模不会为下游任务带来负面影响 Model Positional embedding&#xff1a;选择RoPE&#xff0c;反向更新时选择FP32的精度而不是FP16或BP16&#xff0c…

木疙瘩学习-行为添加与控制

这里面都是一些代码逻辑&#xff0c;但是这个平台让用户0代码实现交互&#xff0c;但是难点是&#xff0c;用户需要有一定的业务逻辑转换程序逻辑思维能力&#xff01; 注意&#xff0c;舞台上的任何素材都可以参与程序逻辑&#xff01;前提是我们为素材手动指定名字&#xff…

【详细教程】关于如何使用GitGitHub的基本操作汇总GitHub的密钥配置 ->(个人学习记录笔记)

文章目录 1. Git使用篇1.1 下载安装Git1.2 使用Git 2. GitHub使用篇2.1 如何git与GitHub建立联系呢&#xff1f;2.2 配置公钥 1. Git使用篇 1.1 下载安装Git 点击 官网链接 后&#xff0c;进入Git官网&#xff0c;下载安装包 然后根据系统类型进行下载&#xff0c;一般为wind…

unity3d场景加载

需将场景拖到到file->buildsetting中

基于微信小程序的抢票系统vue+uniapp

1、开发实现微信小程序的抢票系统的整个系统程序&#xff1b; 2、管理员服务端&#xff1b;首页、个人中心、用户管理、票据类型管理、票据信息管理、抢票信息管理、系统管理等。 3、用户微信端&#xff1a;首页、票据信息、我的等相应操作&#xff1b; 4、基础数据管理&#…

k8s 集群部署

目录 1. 集群环境初始化 2. 所有节点安装kubeadm 3. 拉取集群所需镜像 4. 集群初始化 5. 安装flannel网络插件 6. 扩容节点 7. 设置kubectl命令补齐 官网&#xff1a; https://v1-23.docs.kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm/install-kubeadm/ …

SAP业务从ECC升级到SAP S/4HANA有哪些变化?有哪些功能得到增强?

SAP在2015年推出了新一代商务套件SAP S/4 HANA。 SAP S/4 HANA (全称SAP Business suite 4 SAP HANA),这款新产品完全构建于目前先进的内存平台SAP HANA 之上&#xff0c;同时采用现代设计理念&#xff0c;通过SAP Fiori 提供精彩的用户体验 (UX)。提供比ECC更强大的功能。S/4h…

Docker容器技术实战2

4、docker仓库 docker hub 注册账号&#xff1a;https://hub.docker.com/ 上传自己的镜像仓库 创建自己的仓库webserver 拉取镜像 Registry工作原理 配置镜像加速器 搭建私有仓库 上传镜像 在server1上 在server2&#xff08;纯净&#xff09;上 强制使用非加密私有仓库 5、…

NEFU数字图像处理(三)图像分割

一、图像分割的基本概念 1.1专有名词 前景和背景 在图像分割中&#xff0c;我们通常需要将图像分为前景和背景两个部分。前景是指图像中我们感兴趣、要分割出来的部分&#xff0c;背景是指和前景不相关的部分。例如&#xff0c;对于一张人物照片&#xff0c;人物就是前景&…

百货中心供应链管理系统

毕业设计说明书 百货中心供应链管理系统 百货中心供应链管理系统 摘要 近年来&#xff0c;随着计算机技术的发展&#xff0c;以及信息化时代下企业对效率的需求&#xff0c;计算机技术与通信技术已经被越来越多地应用到各行各业中去。百货中心作为物流产业链中重要的一环&a…

Cesium弹窗可随地图移动

目录 项目地址实现效果实现方法 项目地址 https://github.com/zhengjie9510/webgis-demo 实现效果 实现方法 handler new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas) handler.setInputAction((click) > {if (listener) {listener()listener undefinedthis.v…

黑客在Pwn2Own Toronto上以58个零日漏洞赚取超过100万美元

Pwn2Own Toronto 2023黑客大赛已经圆满结束&#xff0c;安全研究人员通过攻击消费类产品的58个零日漏洞&#xff08;以及多个漏洞碰撞&#xff09;赚取了1,038,500美元。此次比赛由趋势科技的零日倡议&#xff08;Zero Day Initiative&#xff0c;简称ZDI&#xff09;组织&…

电子电器架构 —— 车载网关初入门(二)

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 PS:小细节,本文字数5000+,详细描述了网关在车载框架中的具体性能设置。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 没有人关注你。也无需有人关注你。你必须承认自己的价值,你不能站在他…

WMS基础流程和设计

文章目录 一、WMS的含义和系统综述1.1 WMS含义1.2 系统综述 二、WMS系统关键概念2.1 概念解释2.1.1 区域2.1.2 波次管理2.1.3 作业2.1.4 提货方式2.1.5 批号要求2.1.6 容器2.1.7 暂存区2.1.8 复核台2.1.9 补货2.1.10 订单类别 2.2 仓储作业中的岗位 三、WMS基础资料的内容及初装…

剑指JUC原理-2.线程

创建和运行线程 直接使用Thread // 创建线程对象 Thread t new Thread() {public void run() {// 要执行的任务} }; // 启动线程 t.start();--------------------------------------------------// 构造方法的参数是给线程指定名字&#xff0c;推荐 Thread t1 new Thread(&…

力扣 三数之和 双指针 java

Problem: 15. 三数之和 时间复杂度: O ( n 2 ) O(n^2) O(n2) &#x1f351; AC code class Solution {public List<List<Integer>> threeSum(int[] nums) {List<List<Integer>> res new ArrayList<>();int len nums.length; if(len < 3…

【卷积神经网络】YOLO 算法原理

在计算机视觉领域中&#xff0c;目标检测&#xff08;Object Detection&#xff09;是一个具有挑战性且重要的新兴研究方向。目标检测不仅要预测图片中是否包含待检测的目标&#xff0c;还需要在图片中指出它们的位置。2015 年&#xff0c;Joseph Redmon, Santosh Divvala 等人…

No173.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

队列概念|循环队列的实现

前言 今天我们将学习循环队列实现&#xff0c;我们首先介绍队列的概念和结构&#xff0c;之后一步步讲解循环队列由来与实现。 一、队列的概念与结构 1、队列的概念 队列&#xff1a; 只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表。队列是…