C++11(4)

news2024/9/21 23:05:59

万众瞩目的C++11特辑来了,本章将继续讲解C++11更新的内容,不过C++11的内容也快接近尾声了。

目录

10。lambda表达式

11。lambda捕捉列表[]

捕捉列表说明

lambda捕捉列表实际应用


10。lambda表达式

#include<iostream>
using namespace std;
#include<algorithm>
#include<vector>
struct Goods
{
    string _name; // 名字
    double _price; // 价格
    int _evaluate; // 评价
    //...

    Goods(const char* str, double price, int evaluate)
        :_name(str)
        , _price(price)
        , _evaluate(evaluate)
    {}
};

int main()
{
    //lambda表达式
    // lambda 匿名函数的对象, 所以肯定有类型,所以肯定有返回值
    //即返回一个lambda类型的对象

    auto ret = [](int x, int y)->int {return x + y; };
    //为什么用auto自动推导呢,因为lambda的类型lambda_uuid过于复杂了,详情请看汇编
    //这个切记lambda的返回值不是返回函数体里面运算得出了类型,虽然return了
    cout << ret(1, 1) << endl;
    cout << ret(3, 1) << endl;
    //上面展示的是lambda表达式的完整形式
    //最前面的捕捉列表,没有捕捉对象可以没有任何东西,但是[]必须写上
    //后面的参数部分,确实不需要传参可以不写,明确函数体返回值的可以不写->返回值
    //函数体部分不可以省略
    //所以只有[]和函数体是必须写上的

    // 返回值类型可自动推导类型,所以可以省略
    // 无参数可以省略

    auto it = []
        {
            cout << "wfwfwq" << endl;
            cout << "wfwfwq" << endl;
            cout << "wfwfwq" << endl;
            cout << "wfwfwq" << endl;
            //return 0;//有没有return都无所谓的,只要返回值确定或者无返回值
        };
    it();//外部调用方法
    return 0;
}

//通过观察底层汇编可以发现lambda和仿函数的实现有点像,
//所以这两个是可以互相替代使用的

然而我们会发现,在之前使用的库里面的sort函数就使用了仿函数,所以我们可以使用lambda表达式对其进行改造。
struct comp1//比较价格的升序
{
    bool operator()(const Goods& gl, const Goods& gr)
    {
        return gl._price < gr._price;
    }
};

struct comp2//比较价格的降序
{
    bool operator()(const Goods& gl, const Goods& gr)
    {
        return gl._price > gr._price;
    }
};
int main()
{
    vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 3 }, { "菠萝", 1.5, 4 } };
    sort(v.begin(), v.end(), comp1());
    sort(v.begin(), v.end(), [](const Goods& gl, const Goods& gr) 
        {
            return gl._price > gr._price;
        });
    return 0;
}

以下为调试结果:

//使用lambda表达式的优点是便于使用者马上就可以看出在进行什么操作,升序排列降序排列什么的
//比较直观
//其实也不需要去看底层这个comp1作为一个类,comp1()就是匿名函数对象,那和lambda的本质不是一样了吗

11。lambda捕捉列表[]

//接着聊一下捕捉列表是个什么东西,有什么作用

//捕捉列表的本质就是在初始化函数的参数!!!
int main()
{
    int a = 2;
    int b = 5;
    auto swap1 = [](int& x, int& y)
        {
            //只能用当前lambda局部域和捕捉的对象
            int temp = x;
            x = y;
            y = temp;
        };
    swap1(a, b);
    cout << a << endl;
    cout << b << endl;
    int c = 6;
    int d = 7;
    //发现swap1将两个值交换了
    auto swap2 = [c, d]()mutable
        {
            // 只能用当前lambda局部域和捕捉的对象
            int temp = c;
            c = d;
            d = temp;
            //上面报错的信息为必须是可修改的左值
            //说明传值捕捉指定参数个体本质是一种拷贝,并且const修饰了
            //解决办法在[]后面加上()mutable,mutable的作用是去除const属性

        };
    swap2();//传值捕捉还是需要调用的,只是参数固定了,不需要写了(不要忘了调用)
    cout << c << endl;
    cout << d << endl;
    //发现没有交换成功, 结合上面swap1交换成功的例子可以看出传值捕捉
    //修改了不会影响外面被捕捉的值,因为是一种拷贝,如果执意要改需要传引用捕捉
    //这里侧面体现了mutable和传值捕捉都没有什么实际价值

    auto swap3 = [&c, &d]//这里不是取地址是引用
        {
            int tmp = c;
            c = d;
            d = tmp;
        };
    swap3();
    cout << c << endl;
    cout << d << endl;

    return 0;
}

// 只能用当前lambda局部域和捕捉的对象和全局对象

捕捉列表说明

int main()
{
    //还有其他的捕捉方式
    int a = 0;
    int b = 1, c = 1;
    int d = 2;
    // 所有值传值捕捉
    auto func1 = [=]
        {
            int ret = a + b + c + d;
            return ret;//如果要取到ret的值就需要返回,因为出了func1函数的局部域就销毁了
        };
    // 所有值传引用捕捉
    auto func2 = [&]
        {
            a++;
            b++;
            c++;
            d++;
            int ret = a + b + c + d;
            return ret;//如果要取到ret的值就需要返回,因为出了func1函数的局部域就销毁了
        };
    // 混合捕捉
    auto func3 = [&a, b]
        {
            a++;
            //b++;//无法修改
            int ret = a + b;
            return ret;//如果要取到ret的值就需要返回,因为出了func1函数的局部域就销毁了
        };
    // 混合捕捉
    // 除d以外所有值以引用方式捕捉,d用传值捕捉

    auto func4 = [&, d]
        {
            a++;
            b++;
            c++;
            //d++;
            int ret = a + b + c + d;
            return ret;//如果要取到ret的值就需要返回,因为出了func1函数的局部域就销毁了
        };
    // 除d以外所有值以传值方式捕捉,d用传引用捕捉
    auto func5 = [=, &d]() mutable
            {
                a++;
                b++;
                c++;
                d++;
                int ret = a + b + c + d;
            };
    int p1 = func1();
    int p2 = func2();
    int p3 = func3();
    int p4 = func4();
    cout << p1 << endl;
    return 0;
    //太多组合方式了

}

lambda捕捉列表实际应用

下面的例子是一个计算利息的程序(后面会不断的使用这个例子)

class Rate
{
public:
    Rate(double rate) 
        : _rate(rate)
//一般是放在下面
    {}

    double operator()(double money, int year)
    {
        return money * _rate * year;
//计算当年的利息
    }
private:
    double _rate;
};

int main()
{
  
 // 函数对象
    double rate = 0.015;
    Rate r1(rate);
    cout << r1(10000, 2) << endl;

    // lambda[]捕捉在全局域捕捉
    auto r2 = [rate](double monty, int year)->double
    {
        return monty * rate * year;
    };

    cout << r2(10000, 2) << endl;

    int x = 1, y = 2;
  
 //执行之后发现捕捉列表也不是什么都捕捉的,对函数体里面有用的变量才捕捉
    auto r3 = [=](double monty, int year)->double
    {
        return monty * rate * year;
    };

    cout << r3(10000, 2) << endl;


    return 0;
}

现在解决一下关于lambda对象的类型的问题:请看下图

可以看到图片//lambda那里有一个call   <lambda_什么什么>很长的一串字符,这个就是lambda对象的类型,这个可以看成是一个类(因为有类操作符::),类就是类型,由于太长了就简称lambda_uuid,所有lambda是有类型的并且可以取到的

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

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

相关文章

手把手教你:在微信小程序中加载map并实现拖拽添加标记定位

本文将为大家详细介绍如何在微信小程序中加载map组件&#xff0c;并实现拖拽标记定位功能。 实现步骤 1、首先&#xff0c;我们需要在项目的app.json文件中添加map组件的相关配置。如下所示&#xff1a; {"pages": ["pages/index/index"],"permiss…

robomimic基础教程(三)——自带算法

robomimic自带几个高质量的离线学习算法的实现&#xff0c;包括模仿学习和强化学习&#xff0c;并提供相关工具来辅助你轻松构建自己的学习算法。 一、模仿学习&#xff08;Imitation Learning&#xff09; 1. BC (Behavioral Cloning) Vanilla Behavioral Cloning, 旨在通过…

使用knn算法对iris数据集进行分类

程序功能 使用 scikit-learn 库中的鸢尾花数据集&#xff08;Iris dataset&#xff09;&#xff0c;并基于 KNN&#xff08;K-Nearest Neighbors&#xff0c;K近邻&#xff09;算法进行分类&#xff0c;最后评估模型的准确率。 代码 from sklearn import datasets# 加载鸢尾…

链表在开空间时候出现的问题

题目&#xff1a; 第一种写法完整答案&#xff1a; 第二种写法完整答案&#xff1a;

【机器学习】--- 自监督学习

1. 引言 机器学习近年来的发展迅猛&#xff0c;许多领域都在不断产生新的突破。在监督学习和无监督学习之外&#xff0c;自监督学习&#xff08;Self-Supervised Learning, SSL&#xff09;作为一种新兴的学习范式&#xff0c;逐渐成为机器学习研究的热门话题之一。自监督学习…

【C++题解】1996. 每个小组的最大年龄

欢迎关注本专栏《C从零基础到信奥赛入门级&#xff08;CSP-J&#xff09;》 问题&#xff1a;1996. 每个小组的最大年龄 类型&#xff1a;二维数组 题目描述&#xff1a; 同学们在操场上排成了一个 n 行 m 列的队形&#xff0c;每行的同学属于一个小组&#xff0c;请问每个小…

PCIe进阶之TL:Completion Rules TLP Prefix Rules

1 Completion Rules & TLP Prefix Rules 1.1 Completion Rules 所有的 Read、Non-Posted Write 和 AtomicOp Request 都需要返回一个 Completion。Completion 有两种类型:一种带数据负载的,一种不带数据负载的。以下各节定义了 Completion header 中每个字段的规则。 C…

【磨皮美白】基于Matlab的人像磨皮美白处理算法,Matlab处理

博主简介&#xff1a;matlab图像代码项目合作&#xff08;扣扣&#xff1a;3249726188&#xff09; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本次案例是基于Matlab的图像磨皮美白处理&#xff0c;用matlab实现。 一、案例背景和算法介绍 …

【图像匹配】基于SURF算法的图像匹配,matlab实现

博主简介&#xff1a;matlab图像代码项目合作&#xff08;扣扣&#xff1a;3249726188&#xff09; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本次案例是基于基于SURF算法的图像匹配&#xff0c;用matlab实现。 一、案例背景和算法介绍 前…

7天速成前端 ------学习日志 (继苍穹外卖之后)

前端速成计划总结&#xff1a; 全26h课程&#xff0c;包含html&#xff0c;css&#xff0c;js&#xff0c;vue3&#xff0c;预计7天内学完。 起始日期&#xff1a;9.16 预计截止&#xff1a;9.22 每日更新&#xff0c;学完为止。 学前计划 课…

文字loading加载

效果 1. 导入库 import sys from PyQt5.QtCore import QTimer, Qt, QThread, pyqtSignal from PyQt5.QtGui import QPainter, QFont, QColor, QBrush from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QProgressBar, QLabel 代码首先导入了P…

编辑器拓展(入门与实践)

学习目标:入门编辑器并实现几个简单的工具 菜单编辑器 MenuItem [MenuItem("编辑器拓展/MenuItem")]static void MenuItem(){Debug.Log("这是编辑器拓展");} } 案例 1&#xff1a;在场景中的 GameObject 设置 1. 设置面板2. 直接创建 GameObject 结构…

2-96 基于matlab的SMOTE数据扩充算法

基于matlab的SMOTE数据扩充算法&#xff0c;主动设置数据扩充百分比&#xff0c;并考虑最近邻居数进行扩充&#xff0c;计算样本到他所在类样本集中所有样本距离&#xff0c;从样本的K近邻中随机选择若干样本添加到扩充样本集。程序已调通&#xff0c;可直接运行。 下载源程序…

c++中引用是通过指针的方式实现

其实在汇编层面上&#xff0c;引用的代码和指针的代码是一致的。 先看指针情况下的代码分析&#xff0c;如下所示&#xff1a; #include <iostream>using namespace std;void fuzhi(int *x)//引用传参 {*x 10; }int main(int argc, char** argv) {int a 0;int b;a …

LeetCode[简单] 283.移动零

给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 思路&#xff1a;利用快慢指针&#xff0c;快指针遍历数组&#xff0c;慢指针是非零元素索…

【D3.js in Action 3 精译_023】3.3 使用 D3 将数据绑定到 DOM 元素

当前内容所在位置&#xff1a; 第一部分 D3.js 基础知识 第一章 D3.js 简介&#xff08;已完结&#xff09; 1.1 何为 D3.js&#xff1f;1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践&#xff08;上&#xff09;1.3 数据可视化最佳实践&#xff08;下&#xff09;1.4 本…

销管系统 —— P14 菜单项悬停高亮显示遇到的问题

悬停在子菜单背景颜色并没有显示&#xff0c;为什么&#xff1a; 什么是后代选择器 —— 选中父元素 后代中 满足条件的元素&#xff1b;这个子菜单menu—item它既满足上面的也满足下面的&#xff0c;按这个顺序的话&#xff0c;下面的就被覆盖了&#xff08;CSS优先级规则&…

Nginx实用篇:实现负载均衡、限流与动静分离

Nginx实用篇&#xff1a;实现负载均衡、限流与动静分离 | 原创作者/编辑&#xff1a;凯哥Java | 分类&#xff1a;Nginx学习系列教程 Nginx 作为一款高性能的 HTTP 服务器及反向代理解决方案&#xff0c;在互联网架构中扮演着至关重要的角色。它…

可视化深度网络的强大工具:Grad-CAM介绍与使用步骤

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发…

第一次安装Pytorch

1、新版本的Anaconda内置的python版本是3.12&#xff0c; 目前 Windows 上的 PyTorch 仅支持 Python 3.8-3.11;不支持 Python 2.x。 1、创建运行环境 在不创建虚拟环境的情况下&#xff0c;不建议使用最新的Python和Anaconda。 在几次失败后&#xff0c;我使用的是Anaconda3-2…