C++11 lambda表达式学习

时间:2021-07-11 18:41:09

最近在接手一个模块,看到了很多奇葩的语法,查了一下是lambda表达式,这块还真不了解。周末学习一下记录记录。

lambda表达式是C++11最重要也最常用的一个特性之一。lambda来源于函数式编程的概念,也是现代编程语言的一个特点。目前支持lamdba的语言不少,如python,C++11, Java等。

 

lambda表达式的语法归纳如下

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

1).capture是捕获列表;

2).params是参数表;(选填)

3).opt是函数选项;可以填mutable,exception,attribute(选填)

mutable说明lambda表达式体内的代码可以修改被捕获的变量,并且可以访问被捕获的对象的non-const方法。

exception说明lambda表达式是否抛出异常以及何种异常。

attribute用来声明属性。

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

5).body是函数体。

 

捕获列表说明:lambda表达式的捕获列表精细控制了lambda表达式能够访问的外部变量,以及如何访问这些变量。

1).[]不捕获任何变量。

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

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

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

5).[bar]按值捕获bar变量,同时不捕获其他变量。

6).[this]捕获当前类中的this指针,让lambda表达式拥有和当前类成员函数同样的访问权限。如果已经使用了&或者=,就默认添加此选项。捕获this的目的是可以在lamda中使用当前类的成员函数和成员变量。

 

注意点:

(1) 如果是使用按值捕获,则在定义时已经将值复制

     如果是使用按引用捕获,则在实际使用时才进行取值。 

(2) printf函数/std::cout 的计算顺序:先从右到左压栈,然后从左到右出栈。

 

测试例子:

 1 #include <iostream>
 2 
 3 int main()
 4 {
 5     int x = 1, y = 1;
 6 
 7     //不带参数, 不捕获变量
 8     auto f1 = []{std::cout<<"hello"<<std::endl;};
 9     f1();   //输出:hello
10 
11     //不带参数, 值传递方式捕获外部变量
12     auto f2 = [=]() {return x + 1;};
13     std::cout << x << " " << f2() << std::endl; //输出:1 2
14 
15     //带一个参数
16     //值传递捕获y, 引用传递x    
17     auto f3 = [&x,y](int a) mutable {x = x + a + y; ++y; return x;};
18     std::cout << "x = " << x
19             << ", y = " << y 
20             << ", f3(5) = " << f3(5) << std::endl;
21 
22     //综合例子
23     int a = 1, b = 1, c = 1;
24     auto m1 = [a, &b, &c]() mutable {
25         auto m2 = [a, b, &c]() mutable {
26             std::cout << "m2():"<< "a = " << a
27                     << ", b = " << b
28                     << ", c = " << c << '\n';
29             a = 4; b = 4; c = 4;
30         };
31         a = 3; b = 3; c = 3;
32         m2();
33     };
34 
35     a = 2; b = 2; c = 2;
36 
37     m1();                             // 调用 m2() 并打印 123
38     std::cout << "main():"<< "a = " << a
39             << ", b = " << b
40             << ", c = " << c << '\n';
41 
42     return 0;
43 }

 编译执行:

g++ -std=c++11 test.cpp 

hello
1 2
x = 7, y = 1, f3(5) = 7
m2():a = 1, b = 2, c = 3
main():a = 2, b = 3, c = 4

 

参考:

http://zh.cppreference.com/w/cpp/language/lambda

https://blog.csdn.net/fjzpdkf/article/details/50249287

https://blog.csdn.net/tommyzht/article/details/47334059