美文网首页
C++11之lambda表达式初探

C++11之lambda表达式初探

作者: 小pb | 来源:发表于2018-04-11 18:45 被阅读25次

    C++11 中的lambda表达式,用于顶一个并创建一个匿名的函数对下,以简化编程工作。
    一. 语法
    [ capture-list ] ( params ) mutable exception attribute -> ret { body }
    [函数对象参数] (操作符重载函数参数) mutable或exception声明 ->返回值类型 {函数体}
    1、函数对象参数
    函数对象参数,是标识一个lambda表达式的开始,这部分必须存在,不能省略。函数对象参数是传递给编译器自动生成的函数对象类的构造函数。换句话说,Lambda函数可以引用在它之外声明的变量. 这些变量会在方括号[]内. 成为一个闭包。下面是一些常用的例子。

        []        // 未定义变量.试图在Lambda内使用任何外部变量都是错误的.
        [x, &y]   // x 按值捕获, y 按引用捕获.
        [&]       // 用到的任何外部变量都隐式按引用捕获(包括Lambda所在类的this)
        [=]       // 用到的任何外部变量都隐式按值捕获(包括Lambda所在类的this)
        [&, x]    // x显式地按值捕获. 其它变量按引用捕获
        [=, &z]   // z按引用捕获. 其它变量按值捕获
    
    1. 操作符重载函数参数
      标识重载的()操作符的参数,没有参数时,这部分可以省略。参数可以通过按值(如:(a,b))和按引用(如:(&a,&b))两种方式进行传递。
      这就是一个函数声明:

            [&a](int v){ cout << v+a << endl; }
      

    注意这里函数的声明和函数的调用要区分开。

    1. mutable或exception声明

      这部分可以省略。按值传递函数对象参数时,加上mutable修饰符后,可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身)。exception声明用于指定函数抛出的异常,如抛出整数类型的异常,可以使用throw(int)。

         // 以引用方式传递作用域内所有可见的局部变量(包括this),输出:11 13 12  
       {  
           int a = 10;  
           for_each(vctTemp.begin(), vctTemp.end(), [&](int v)mutable{ cout << v+a << endl; a++; });  
           cout << a << endl;  
       } 
      
       // 以值方式传递局部变量a,输出:11 13 10  
       {  
           int a = 10;  
           //注意:在lambda表达式中的 a 只是一个拷贝,添加mutable之后,可以修改a的值,但只是修改拷贝的a  
           for_each(vctTemp.begin(), vctTemp.end(), [a](int v)mutable{ cout << v+a << endl; a++; });  
           cout << a << endl;  
       }  
      
    2. ->返回值类型,
      标识函数返回值的类型,当返回值为void,或者函数体中只有一处return的地方(此时编译器可以自动推断出返回值类型)时,这部分可以省略。

    3. 函数体,标识函数的实现,用{}括起来的,这部分不能省略,但函数体可以为空,这部分和c++正常的函数体一样。

    这里给出一个完整的写法:

      [](int x, int y) -> int { int z = x + y; return z; }
    

    End

    相关文章

      网友评论

          本文标题:C++11之lambda表达式初探

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