好吃的语法糖

只有C11以上才支持,不要忘记开-std=c++11

定义

组成如下

[capture list] (params list) mutable exception attribute ->return type { function body }
  • capture list

    可以捕获外部变量,可以为空。

  • params list

    参数列表

  • mutable关键字

    可选,写上后表示可以修改capture list里面的东西

  • exception

    可选,写上后可以表示抛出异常的类型

  • attribute

    可选,比如说可以写__attribute__((always_inline))

  • -> return type

    可选,表示返回值类型(如果不写则自动匹配)

一般来说,有下面几种形式

  1. 全部都写
  2. []()->reT{}
  3. [](){}
  4. []{}

在这样子声明后,会返回一个function类

function类于C11提出,效果类似于函数指针,但是这里不仅仅可以存放函数指针,还可以存放其他通过()调用的操作,比如:

  1. 一般函数指针
  2. Lambda
  3. 仿函数
  4. 其他

写法如下

#include <functional>    //引入库
std::function<ret(para list)> a;    //注意如果在类的里面,std改为T

举个例子

using namespace std;
function<int(int,int)> mmax = [](int a,int b){
    return a>b?a:b;
};
cout << mmax(1,2) << endl;

在本文中会使用auto完成这项工作(如果不使用auto则无法使用参数缺省功能)

捕获

值捕获

如果使用值捕获,代码则会在表达式被声明时复制这些值并保存起来

int a = 123;
auto func = [a](){
    cout << a << endl;
};
a = 321;
func();    //输出123

如果这么写的话,是不支持修改被捕获的值,即这段函数里的a

那要怎么办呢?加上mutable关键字就好

int main() {
    int a = 123;
    auto func = [a]()mutable{
        a = 1111;
        cout << a << endl;
    };
    a = 321;
    func();             //输出1111
    cout << a << endl;  //输出321
}

引用捕获

想要实现lambda里面的值和外面的值同步变化,在相关变量前面加上&就好

int main() {
    int a = 123;
    auto func = [&a]() {
        cout << a << endl;
        a = 987;
    };
    a = 321;
    func();            //输出321
    cout << a << endl; //输出987
}
这里不支持在&号前面添加const关键字

一旦使用引用捕获,其实和使用参数没有差别。

隐式捕获(不推荐)

如果我们想要让所有的都被捕获,且用值捕获的方法,我们这么写

auto func = [=](){};

如果我想让a用引用捕获,其它的都用值捕获,这样写

auto func = [=,&a](){};

如果我想要全部用索引捕获,a用值,这么写

auto func = [&,a](){};
请注意,捕捉的列表不允许重复传参,会引起编译时候的错误

比如[&,&a]

捕获this

如果我写在类的成员函数里面,那么我可以这么些

auto func = [this](){};

参数/异常/特性

均与一般的函数完全一样

特别注意捕获和参数可能有重叠的地方

返回值

如果在不手动声明的时候,自动调用auto,但可能造成歧义,如下:

auto func = [](int a){
    if(a == 1)return 123;
    else return 321.5;
};

所以必须手动添加相应代码才行

auto func = [](int a) -> double{//返回一个double值
    if(a == 1)return 123;
    else return 321.5;
};

实际运用

比如用在sort里面

vector<int> vec;
sort(vec.begin(),vec.end(),[](int a,int b){
    return a > b;
});

参考文章

Last modification:March 14th, 2020 at 02:09 pm
Compared with money, your comment could inspire me more.
相较于钱财,你的留言更能激发我创作的灵感