• C++lambda表达式


    C++lambda表达式

    捕获方式

    值捕获

    lambda表达式值捕获的变量在lambda函数体内部不可修改,只可读

    在这里插入图片描述

    引用捕获

    lambda表达式可以引用捕获变量、const常量、constexpr常量,捕获后的属性与之间的属性一致

    在这里插入图片描述

    捕获this指针

    成员函数中的lambda表达式默认不能访问成员变量,需要捕获this指针才能访问

    在这里插入图片描述

    class Foo {
    public:
    	void Show() {
    		auto lambda = [this]() {
    			cout << data << endl;
    		};
    		lambda();
    	}
    private:
    	int data=1;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    需要注意的是,this指针只能以值的方式进行捕获,不能以引用的方式捕获

    在这里插入图片描述

    当成员函数中存在局部变量与成员变量同名时,lambda表达式函数体内默认使用局部变量,若没有对其进行捕获,编译报错

    在这里插入图片描述

    如果指定lambda表达式中访问成员变量,可以显示使用this->data,想要在lambda表达式中访问成员变量,需要捕获this指针,除此之外,还可以捕获*this,效果与捕获this指针一样,通常直接捕获this即可

    class Foo {
    public:
    	void Show() {
    		auto lambda = [*this]() {
    			cout << this->data << endl;
    		};
    		lambda();
    	}
    private:
    	int data = 1;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    C++14泛型lambda

    lambda表达式的参数可以使用auto

    auto lambda = [](auto x, auto y) {
    	return x + y;
    };
    cout << lambda(1, 1) << endl;//2
    cout << lambda(string("abc"), string("def")) << endl;//abcdef
    
    • 1
    • 2
    • 3
    • 4
    • 5

    C++20模版lambda

    C++20中lambda表达式可以搭配模版使用

    局部lambda对象搭配模版

    局部lambda对象搭配模版使用只能进行自动推导

    在这里插入图片描述

    全局lambda对象搭配模版使用

    全局lambda对象搭配模版使用必须指定模版参数

    在这里插入图片描述

    lambda表达式使用技巧

    lambda表达式作为函数的返回值

    class Foo {
    public:
    	auto GetLambda() {
    		auto lambda = [this]<typename T>(T val) {
    			data += val;
    			AddData();
    			cout << data << endl;
    		};
    		return lambda;
    	}
    private:
    	int AddData() {
    		return ++data;
    	}
    	int data = 5;
    };
    int main() {
    	Foo foo;
    	auto lambda = foo.GetLambda();
    	lambda(3);
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    需要注意的是,访问限定符只在编译阶段发挥作用,只要编译阶段可以"骗过"编译器,main函数中的lambda就能在运行时访问AddData和data

    lambda表达式递归

    C++lambda表达式递归的错误写法

    在这里插入图片描述

    原因并不是没有捕获lambda,而是无法捕获lambda

    在这里插入图片描述

    想要lambda表达式实现递归,可以通过参数或者包装器完成

    通过function实现lambda的递归

    function<int(int)> lambda = [&lambda]<typename T>(T n) {
        if (n <= 2) {
            return n;
        }
        return lambda(n - 1) + lambda(n - 2);
    };
    cout << lambda(10) << endl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    通过包装器完成lambda表达式的递归时,必须以引用的方式捕获,否则可能出现错误。

    在这里插入图片描述

    通过泛型lambda实现递归

    auto lambda = [](auto&& self,int n) {
        if (n <= 2) {
            return n;
        }
        return self(self,n - 1) + self(self,n - 2);
    };
    cout << lambda(lambda,10) << endl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    lambda表达式搭配库函数使用

    lambda表达式搭配库函数使用可以自定义运算规则和比较规则

    vector<int> nums = { 1,2,3,-1,8,9,-10 };
    std::transform(nums.begin(), nums.end(), nums.begin(), [](int n) {
        return n - 3;//将nums中的每一个数-3
    });
    std::for_each(nums.begin(), nums.end(), [](int n) {
        cout << n << ' ';//打印nums中每一个数
    });
    cout << endl;
    std::sort(nums.begin(), nums.end(), [](int l, int r) {
        return abs(l) < abs(r);//按照绝对值大小排序
    });
    std::for_each(nums.begin(), nums.end(), [](int n) {
        cout << n << ' ';
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    unordered_map,unordered_set模拟实现
    JAVA计算机毕业设计电竞教育公司Mybatis+系统+数据库+调试部署
    串口中断(9)即时解析用户自定义通讯协议--接收数据固定情况
    论文总结-交通预测(未完成)
    HTML+CSS大作业:使用html设计一个简单好看的公司官网首页 浮动布局
    Service Mesh和Kubernetes:加强微服务的通信与安全性
    Go并发编程之二
    Vue源码系列讲解——生命周期篇【一】(综述)
    【数据结构与算法】之深入解析“网格游戏”的求解思路和算法示例
    【云岚到家】-day02-2-客户管理-认证授权
  • 原文地址:https://blog.csdn.net/Slowstep_/article/details/133588988