【C++】lambda表达式

本文详细介绍C++中lambda表达式的基础语法、参数捕获模式、新特性如捕捉表达式和泛型表达式,以及实战应用实例。涵盖了从基本用法到高级技巧,适合深入理解C++匿名函数的开发者阅读。

C++中 lambda 表达式

参考文章:https://www.jianshu.com/p/d686ad9de817

lambda 表达式C++11引入的,可以编写内嵌的匿名函数,代替独立函数等。在C++14中添加新特性,又加以强化。

基本语法

// 完整语法
[ capture-list ] ( params ) mutable(optional) constexpr(optional)(c++17) exception attribute -> ret { body } 

// 可选的简化语法
[ capture-list ] ( params ) -> ret { body }     
[ capture-list ] ( params ) { body }    
[ capture-list ] { body } 

参数说明:

  • capture-list:捕捉列表,这个不用多说,前面已经讲过,记住它不能省略;

  • params:参数列表,可以省略(但是后面必须紧跟函数体);

  • mutable:可选,将lambda表达式标记为mutable后,函数体就可以修改传值方式捕获的变量;

  • constexpr:可选,C++17,可以指定lambda表达式是一个常量函数;

  • exception:可选,指定lambda表达式可以抛出的异常;

  • attribute:可选,指定lambda表达式的特性;

  • ret:可选,返回值类型;

  • body:函数执行体

常见写法

  1. 基本表达式

    auto basicLambda = [] {
        cout << "Basic Lambda Express!" << endl;
    };
    basicLambda();
    
  2. 带参数

    auto add = [](int a, int b) -> int {
        return a + b;
    };
    cout << add(2, 3);
    
  3. 捕获变量

    // [] 其实就是一个闭包,用来定义捕捉模式以及变量,表示的是lambda捕捉块
    int x = 10;
    auto add_x = [x](int a) {       // 复制捕捉x,不可以修改x
        return a + x;
    };
    auto multiply_x = [&x](int a) { // 引用捕捉x,可以修改x
        return a * x;
    };
    cout << add_x(10) << ' ' << multiply_x(10) << endl;
    
    // mutbale 关键字可以让复制捕捉方式的表示修改参数
    auto add_x_mutable = [x](int a) mutable {
        x *= 2;
        return a + x;
    };
    cout << add_x_mutable(10) << ' ' << x << endl;
    
  4. lambda 表达式禁用了辅助操作符,但是没有禁用复制构造函数

    // add_x_mutable 是上面定义的
    auto add_copy = add_x_mutable;
    cout << add_copy(10) << ' ' << x << endl;
    
  5. lambda 表达式作为传递的参数

    int value = 3;
    vector<int> v = {1, 2, 3, 5, 4, 7};
    int count = count_if(v.begin(), v.end(), [value](int x) {return x > value;});
    cout << count << endl;
    
    vector<int> vt(10);
    int a = 0;
    int b = 0;
    generate(v.begin(), v.end(), [&a, &b] {
        int value = b;
        b = b + a;
        a = value;
    });
    for(auto element: vt) {
        cout << element << ' ';
    }
    cout << endl;
    
  6. 常见捕获形式

    • []:默认不捕获任何变量;

    • [=]:默认以值捕获所有变量;

    • [&]:默认以引用捕获所有变量;

    • [x]:仅以值捕获x,其它变量不捕获;

    • [&x]:仅以引用捕获x,其它变量不捕获;

    • [=, &x]:默认以值捕获所有变量,但是x是例外,通过引用捕获;

    • [&, x]:默认以引用捕获所有变量,但是x是例外,通过值捕获;

    • [this]:通过引用捕获当前对象(其实是复制指针);

    • [*this]:通过传值方式捕获当前对象;

    最好不要使用 [=] [&] 捕获所有变量,可能会出现悬挂引用

新特性

捕捉表达式
int x1 = 5;
auto y = [&r = x1, x1 = x1 + 1] {
    r += 2;
    return x1 * x1;
};
cout << x1 << ' ' << y() << endl;

auto z = [str = "string"] {
    return str;
};
cout << z() << endl;
泛型表达式
auto  add1 = [](auto x, auto y) { return x + y; };
cout <<  add1(2, 3) << ' ' << add1(2.3, 2.3) << endl;
函数对象
for_each(vt.begin(), vt.end(), [](int x) { cout << x << ' '; });
cout << endl;

源代码参考

https://github.com/EricPengShuai/Interview/blob/main/c%2B%2B2.0/lambda.cpp

同步在个人博客:https://ericpengshuai.github.io/bian-cheng-bei-wang/eedf7c85da84.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值