【C++】lambda表达式


【C++】lambda 表达式

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

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();
  1. 带参数

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

    // [] 其实就是一个闭包,用来定义捕捉模式以及变量,表示的是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;
  1. lambda 表达式禁用了辅助操作符,但是没有禁用复制构造函数

    // add_x_mutable 是上面定义的
    auto add_copy = add_x_mutable;
    cout << add_copy(10) << ' ' << x << endl;
  1. 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;
  1. 常见捕获形式

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

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

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

    • [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://www.jianshu.com/p/d686ad9de817


文章作者: PengShuai
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 PengShuai !
评论
  目录