c++11 lamdba

c++11 lamdba详解

一、 语法

[capture] (parameters) mutable ->return_type{statement}
1、 [capture] 捕获列表: 捕捉列表总是出现在lamdba函数的开始处。事实上,[]是lambda引出符。编译器根据该引出符判断接下来的代码是否是lambda函数。

捕获类型 说明
[var] 值传递方式捕捉变量var
[=] 值传递方式捕捉所有父作用域的变量(包括this)
[&var] 引用传递捕捉变量var
[&] 引用传递捕捉所有父作用域的变量(包括this)
[this] 值传递方式捕捉当前的this指针

2、 (parameters) 参数列表: 和函数的参数列表一致。如果不需要参数列表,则可以连同括号()一起省略。
3、 mutable:mutable 修饰符。 默认情况下,lamdba捕获的变量都是const的,要想在lamdba的函数体里修改通过值捕获的变量,需要使用mutable修饰符。
4、 -> return_type: 返回类型,不需要返回值的时候可以连同符合->一起省略。
5、 {statement}: 函数体,内容与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。

二、 实例

实例1、 以值捕获a
void test1() {
    int a = 3;
    [a]()->int{ return a + 4; }();
    [a]()->int{ return ++a; }(); // error,因为以值捕获a,捕获的变量a在lamdba里是const的,所以不能修改a的值
    [a]() mutable -> int {return ++a;}(); // ok, 通过mutable修饰符之后,可以修改a的值了。这里要注意a的值,执行完lamdba表达式后,a=3,原因见实例2.
}

实例2、 以值捕获a,详解捕获的时机
void test2_1(){
   int a = 3;
   auto f = [a]()->int{return a+3;};
   a = 100;
   auto b = f(); // b为6,lamdba捕获的时机是lamdba被创建时,当lamdba被创建时,a=3,所以b=3+3=6
};

void test2_2(){
   int a = 3;
   auto f = [a]()mutable->int{return ++a;};
   a = 100;
   auto b = f(); // b为4,原因见test2_1(), 此时a的值为100. 你可能会疑惑为什么a的值是100? 原因见下面
};

个人认为lamdba值捕获的变量,就好像是在lamdba的实现体里定义了一个同名的变量,且是const。如下:
auto f = [a]()mutable->int{return ++a;};
相当于:
auto f = []()mutable->int{const int a = 3; return ++a;}; // 按照这种理解,你应该可以理解test2_1和test2_2的b和a的值了

实例3: 以引用捕获a
void test3() {
   int a = 3;
   auto f = [&a]()->int{return ++a;};
   a = 100;
   auto b = f(); // b=101, a=101 不用怀疑,就是101,如果不知道为什么,想想引用的意义就能理解了
}

你可能感兴趣的:(c++11,lamdba,c++)