C++11之lambda表达式初探

2018-04-11  本文已影响25人  小pb

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

上一篇下一篇

猜你喜欢

热点阅读