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

相关推荐
为何创造硅基生物5 小时前
C++ 独占指针被销毁后,堆也会自己销毁
c++
AC赳赳老秦5 小时前
OpenClaw 助力技术面试:自动生成面试题、模拟面试、整理面试知识点
开发语言·python·面试·职场和发展·自动化·deepseek·openclaw
刘科领5 小时前
修改jdk 第一步: 仓库以及构建(jdk17)
java·开发语言
C+-C资深大佬5 小时前
C++ 中的 constexpr与 const区
java·开发语言·c++
8Qi85 小时前
LeetCode 4:寻找两个正序数组的中位数 —— 二分查找法
java·算法·leetcode·职场和发展·二分查找
仙俊红5 小时前
Java 单例模式:类里面为什么可以有自己类型的字段?
java·开发语言·单例模式
8Qi85 小时前
LeetCode 32:最长有效括号 —— 栈 + 标记法 题解
java·数据结构·算法·leetcode·职场和发展··括号匹配
机器学习之心5 小时前
198种组合算法+优化CNN-LSTM+SHAP分析+新数据预测+多输出!深度学习可解释分析,强烈安利,粉丝必备
深度学习·算法·cnn-lstm·shap分析·198种组合算法
Tairitsu_H5 小时前
[LC优选算法#3] 滑动窗口 | 将x减到0的最⼩操作数 | ⽔果成篮 | 字⺟异位词
c++·算法·leetcode·滑动窗口
_Evan_Yao5 小时前
面向对象实战:用 Java/Python 设计一个简单的“怪物战斗”小游戏
java·开发语言