7.lambda表达式

有几天没写了 最近有点小忙 问题不大

7.1 lambda表达式语法

cpp 复制代码
auto SendCmd = [&](uint8_t cmd)->bool {
			CBinary binTemp = binCmd;
			binTemp.Append(byteVaule).Append(cmd);
			CBinary binRecv;
			if (!SendCheck(binRecv, binTemp))
			{
				return false;
			}
			return true;
		};
//lambda 就是函数 一般我用于在函数内部有重复代码时使用 可以提高代码简洁性
[]  这个是捕获列表 &全部捕获 可以到lambda内部使用变量
() 传入参数 
-> 传出的值的类型 (这个可以不用了 有auto)
{} 里边写函数

7.2 捕获列表

好像有点复杂 分开来写

7.2.1 作用域

[ ] 中得是局部变量 (静态变量可以直接使用)所以

如果将一个lambda表达式定义在全局作用域,那么lambda表达式的捕获列表必须为空。(应该没有人会这么写 )

[ x,y] ===不加&就是只读的捕获 不能对x和y修改

[&x,&y] >> 引用捕获 可读可写

捕获的变量默认为常量,或者说lambda是一个常量函数(类似于常量成员函数)

cpp 复制代码
void bar3()
{
    int x = 5, y = 8;
    auto foo = [x, y]() mutable {
        x += 1;
        y += 2;
        return x * y;
    };
    std::cout << foo() << std::endl;
}//这个样子可以修改内部的值    但还是值传递 外部的x y 不改变
//与&传递有本质区别
语法规定lambda表达式如果存在说明符,那么形参列表不能省略
7.2.2 捕获值和捕获引用
cpp 复制代码
#include <iostream>
int main()
{
    int x = 5, y = 8;
    auto foo = [x, &y]() mutable {
        x += 1;
        y += 2;
        std::cout << "lambda x = " << x << ", y = " << y <<
            std::endl;
        return x * y;
    };
    foo();
    std::cout << "call1 x = " << x << ", y = " << y << std::endl;
    foo();
    std::cout << "call2 x = " << x << ", y = " << y << std::endl;
}
输出结果  lambda []非&传递只传递一次 后面再调用还是这个被lambda修改的值
lambda x = 6, y = 10 
call1 x = 5, y = 10
lambda x = 7, y = 12 //这里 是按照6来 再加1得到7 
call2 x = 5, y = 12

捕获值的变量在lambda表达式定义的时候已经固定下来了,无论函数在lambda表达式定义后如何修改外部变量的值,lambda表达式捕获的值都不会变化,

cpp 复制代码
#include <iostream>
int main()
{
    int x = 5, y = 8;
    auto foo = [x, &y]() mutable {
        x += 1;
        y += 2;
        std::cout << "lambda x = " << x << ", y = " << y <<
            std::endl;
        return x * y;
    };
    x = 9;
    y = 20;
    foo();
}

结果
lambda x = 6, y = 22
7.2.3 特殊的捕获方法

1.[this] ------ 捕获this指针,捕获this指针可以让我们使用this类型的成员变量和函数。

2.[=] ------ 捕获lambda表达式定义作用域的全部变量的值,包括this。

3.[&] ------ 捕获lambda表达式定义作用域的全部变量的引用,包括this。

7.3 lambda表达式的实现原理

lambda表达式与函数对象差不多

lambda表达式在编译期会由编译器自动生成一个闭包类,在运行时由这个闭包类产生一个对象,我们称它为闭包。在C++中,所谓的闭包可以简单地理解为一个匿名且可以包含定义时作用域上下文的函数对象。现在让我们抛开这些概念,观察lambda表达式究竟是什么样子的

7.4 无状态lambda表达式

C++标准对于无状态的lambda表达式有着特殊的照顾,即它可以隐式转换为函数指针

cpp 复制代码
void f(void(*)()) {}
void g() { f([] {}); } // 编译成功
在上面的代码中,lambda表达式[] {}隐式转换为void(*)()类型
的函数指针。同样,看下面的代码:

void f(void(&)()) {}
void g() { f(*[] {}); }

这段代码也可以顺利地通过编译。我们经常会在STL的代码中遇到lambda表达式的这种应用。

7.5 在STL中使用lambda表达式

cpp 复制代码
    std::vector<int> vec = {5, 2, 9, 1, 5, 6};

    // 使用lambda表达式进行排序
    std::sort(vec.begin(), vec.end(), [](int a, int b) {
        return a < b; // 按升序排序
    });

     std::for_each(vec.begin(), vec.end(), [](int num) {
        std::cout << num << " ";
    });

7.6 广义捕获

这个待定

7.7 泛型lambda表达式

cpp 复制代码
int main()
{
	auto foo = [](auto a) { return a; };
	int three = foo(3);
	char const* hello = foo("hello");
}

7.8 常量lambda表达式和捕获*this

同7.6待定

7.9 捕获[=, this]

在C++20标准中,又对lambda表达式进行了小幅修改。这一次修改没有加强lambda表达式的能力,而是让this指针的相关语义更加明确。我们知道[=]可以捕获this指针,相似的,[=,*this]会捕获this对象的副本。但是在代码中大量出现[=]和[=,*this]的时候我们可能很容易忘记前者与后者的区别。为了解决这个问题,在C++20标准中引入了[=, this]捕获this指针的语法,它实际上表达的意思和[=]相同,目的是让程序员们区分它与[=,*this]的不同:

7.10 模板语法的泛型lambda表达式

相关推荐
敲上瘾11 分钟前
操作系统的理解
linux·运维·服务器·c++·大模型·操作系统·aigc
福大大架构师每日一题13 分钟前
文心一言 VS 讯飞星火 VS chatgpt (396)-- 算法导论25.2 1题
算法·文心一言
不会写代码的ys17 分钟前
【类与对象】--对象之舞,类之华章,共绘C++之美
c++
兵哥工控19 分钟前
MFC工控项目实例三十二模拟量校正值添加修改删除
c++·mfc
在下不上天20 分钟前
Flume日志采集系统的部署,实现flume负载均衡,flume故障恢复
大数据·开发语言·python
EterNity_TiMe_28 分钟前
【论文复现】(CLIP)文本也能和图像配对
python·学习·算法·性能优化·数据分析·clip
长弓聊编程29 分钟前
Linux系统使用valgrind分析C++程序内存资源使用情况
linux·c++
陌小呆^O^33 分钟前
Cmakelist.txt之win-c-udp-client
c语言·开发语言·udp
cherub.37 分钟前
深入解析信号量:定义与环形队列生产消费模型剖析
linux·c++
机器学习之心39 分钟前
一区北方苍鹰算法优化+创新改进Transformer!NGO-Transformer-LSTM多变量回归预测
算法·lstm·transformer·北方苍鹰算法优化·多变量回归预测·ngo-transformer