Lambda 表达式

Lambda 表达式

自从c++ 11后引入的新东西,感觉其实很实用,可以简化一些函数的声明,或者把一些短函数直接转化为lambda表达式写入

语法格式

[ captures ] <tparams>(可选)(C++20) ( params ) specifiers(可选) exception attr -> ret requires(可选)(C++20) { body }

[ captures ] ( params ) -> ret { body }

[ captures ] ( params ) { body }

[ captures ] { body }

参数说明

  1. capture 格式

    感觉这个值才是很重要的东西,有2种捕获格式

    1.1 = 以复制的方式使用捕获

    1.2 & 以引用的方式使用捕获

    capture 默认采用 = 进行捕获, 即采用复制的形式捕获.

    参考 cppreference.com 的代码

    若捕获默认是 & ,则后继简单捕获必须不以 & 开始。

    struct S2 { void f(int i); };
    void S2::f(int i)
    {
        [&]{};          // OK :默认以引用捕获
        [&, i]{};       // OK :以值捕获,除了 i 以引用捕获
        [&, &i] {};     // 错误:默认以引用时的以引用捕获
        [&, this] {};   // OK :等价于 [&]
        [&, this, i]{}; // OK :等价于 [&, i]
    }
    
    
        

    若捕获默认是 = ,则后继简单捕获必须以 & 开始或是 *this (C++17 起) 或 this (C++20 起) 。

    struct S2 { void f(int i); };
    void S2::f(int i)
    {
        [=]{};          // OK :默认以复制捕获
        [=, &i]{};      // OK :以复制捕获,除了 i 以引用捕获
        [=, *this]{};   // C++17 前:错误:非法语法
                        // C++17 起: OK :以复制捕获外围 S2
        [=, this] {};   // C++20 前:错误: = 为默认时的 this
                        // C++20 起: OK :同 [=]
    }
        

  2. capture 含义

    在网上找的时候找到一个比较清晰的说明和例子

    int main()
    {
        int x = 10;
        
        auto add_x = [x](int a) { return a + x; };  // 复制捕捉x
        auto multiply_x = [&x](int a) { return a * x; };  // 引用捕捉x
        
        cout << add_x(10) << " " << multiply_x(10) << endl;
        // 输出:20 100
        return 0;
    }
    	

  3. tparams

    这个从 c++20 开始的东西, 根据 cppref 说明是给 lambda 的模版形参

  4. params

    参数列表

  5. specifiers

    只可设置 mutable, constexpr 两种

    如果 lambda 要修改捕获变量, 则需要设置 mutable

    constexpr 这个可以显式的指定, 如果函数内调用自己本身满足 constexpr 的要求, 则也会自动设置为 constexpr

  6. exception/attr

    具体参考 cppref

  7. ret

    lambda 的返回值类型, 如果不设置, 则会自动推倒, 如果 lambda 没有返回值, 这个值则为 void

  8. body

    函数…

Reference

  1. https://www.jianshu.com/p/d686ad9de817

  2. https://zh.cppreference.com/w/cpp/language/lambda

发表评论

电子邮件地址不会被公开。 必填项已用*标注