美文网首页
lambda表达式

lambda表达式

作者: 铭小汁儿 | 来源:发表于2017-06-20 23:14 被阅读0次

    lambda表达式是C++11引入的新特性,用于声明一个函数,因为不需要对这个函数指定函数名,故lambda表达式声明的是匿名函数。lambda来源于函数式编程的概念,也是现代编程语言的一个特点。


    lambda表达式具有如下优点:

    (1)声明式编程风格:匿名定义函数,不需要额外命名函数,可以更直接地写程序。

    (2)在需要的时间和地点实现功能闭包,使编写程序更加灵活。因为其不需要额外命名函数,避免了代码膨胀和功能分散,使得程序更加简洁。


    lambda表达式的语法如下:

    [caputrue](params)opt -> ret { body; };

    (1)caputrue是捕获列表。指明了lambda表达式能访问的外部变量(lambda表达式函数体之外的变量),以及如何访问这些变量。具体情况如下:

    [] 不捕获任何外部变量

    [&] 按引用捕获,即捕获外部作用域中所有变量,并作为引用在函数体中使用。

    [=] 按值捕获,即捕获外部作用域中所有变量,并作为值副本在函数体中使用。

    [=,&a] 按值捕获外部作用域中所有变量,并按引用捕获a变量。

    [b] 按值捕获b变量,同时不捕获其他变量。

    [this] 应用于类中。捕获当前类中的this指针,让lambda表达式拥有和当前类成员函数同样的访问权限,从而可以在lambda中使用当前类的成员函数和成员变量。如果已经在捕获列表中使用了&或者=,那么就默认添加了该选项。

    (2)params是参数列表。表示传给lambda表达式的参数序列,选填。

    (3)opt是函数选项。可以填mutable,exception,attribute(选填一个或者多个)。

    mutable:说明lambda表达式体内的代码可以修改被捕获的变量,如果被捕获的变量是一个对象则可以调用该对象的non-const函数。

    exception:说明lambda表达式是否抛出异常。

    attribute:用来声明函数属性。

    (4)ret是返回类型,选填。

    (5)body是函数体。


    下面以在类中声明lambda表达式为例:

    class A{

    public:

    int a = 0;

    void fun(int x, int y){

    auto a1 = []{ return a; };    //error,没有捕获外部变量

    auto a2 = [=] { return a + x + y; };    //ok

    auto a3 = [&] { return a + x + y; };    //ok

    auto a4 = [this] { return a; };    //ok

    auto a5 = [this]{return a + x + y; };  /*error,因为x,y不是类成员变量,而且没有捕获x,y*/

    auto a6 = [this, x, y]{ return a + x + y; };    //ok

    auto a7 = [this]{ return a ++; };    //ok

    }


    注意事项:

    1、lambda表达式的延迟调用。lambda表达式按值捕获外部变量时,在捕获的瞬间,外部变量的值就被复制了,之后该外部变量值的改变不会对之前捕获到的值有影响。如果希望lambda表达式在调用时即时访问外部变量,应该使用引用方式捕获。

    int a = 0;

    auto func1 = [=] { return a; };

    a ++;

    std::cout << func1() << std::endl;    //输出0

    int b = 0;

    auto func2 = [&b]{ return b; };

    b ++;

    std::cout << func2() << std::endl;    //输出1

    2、按值捕获外部变量时,在lambda表达式中修改它们的副本并不会影响外部的值,但我们仍然无法修改这些副本。如果想修改这些副本,需要显示声明lambda表达式为mutable。lambda表达式定义的是仿函数闭包。lambda表达式捕获到的任何外部变量,最终均会变为闭包类型的成员变量。按照C++11标准,lambda表达式的operator()默认是const的,一个const成员函数是无法修改成员变量的值的。而mutable就取消了operator()的const。

    注:被mutable修饰的lambda表达式就算没有参数也要显示写明参数列表。

    int a = 0;

    auto func1 = [=] { return a++; };    //error

    auto func2 = [=] () mutable { return a++; };    //ok

    相关文章

      网友评论

          本文标题:lambda表达式

          本文链接:https://www.haomeiwen.com/subject/dhiaqxtx.html