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表达式

相关推荐
云卓SKYDROID2 分钟前
除草机器人算法以及技术详解!
算法·机器人·科普·高科技·云卓科技·算法技术
Source.Liu8 分钟前
【用Rust写CAD】第二章 第四节 函数
开发语言·rust
monkey_meng9 分钟前
【Rust中的迭代器】
开发语言·后端·rust
余衫马11 分钟前
Rust-Trait 特征编程
开发语言·后端·rust
monkey_meng15 分钟前
【Rust中多线程同步机制】
开发语言·redis·后端·rust
Jacob程序员17 分钟前
java导出word文件(手绘)
java·开发语言·word
小白学大数据24 分钟前
正则表达式在Kotlin中的应用:提取图片链接
开发语言·python·selenium·正则表达式·kotlin
VBA633726 分钟前
VBA之Word应用第三章第三节:打开文档,并将文档分配给变量
开发语言
半盏茶香26 分钟前
【C语言】分支和循环详解(下)猜数字游戏
c语言·开发语言·c++·算法·游戏
徐子童30 分钟前
双指针算法习题解答
算法