Lambda表达式

Lambda表达式

语法格式

[capture](params) opt -> ret {body;}; - capture: 捕获列表 - params: 参数列表 - opt: 函数选项 - ret: 返回值类型 - body: 函数体

关于Lambda表达式的细节介绍:

  1. 捕获列表: 捕获一定范围内的变量
    • [] - 不捕捉任何变量
    • [&] - 捕获外部作用域中所有变量, 并作为引用在函数体内使用 (按引用捕获)
    • [=] - 捕获外部作用域中所有变量, 并作为副本在函数体内使用 (按值捕获)
      • 拷贝的副本在匿名函数体内部是只读的
    • [=, &foo] - 按值捕获外部作用域中所有变量, 并按照引用捕获外部变量 foo
    • [bar] - 按值捕获 bar 变量, 同时不捕获其他变量
    • [&bar] - 按引用捕获 bar 变量, 同时不捕获其他变量
    • [this] - 捕获当前类中的this指针
      • 让lambda表达式拥有和当前类成员函数同样的访问权限
      • 如果已经使用了 & 或者 =, 默认添加此选项
  2. 参数列表: 和普通函数的参数列表一样
  3. opt 选项 –> 可以省略
    • mutable: 可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身)
    • exception: 指定函数抛出的异常,如抛出整数类型的异常,可以使用throw();
  4. 返回值类型:
    • 标识函数返回值的类型,当返回值为void,或者函数体中只有一处return的地方(此时编译器可以自动推断出返回值类型)时,这部分可以省略
  5. 函数体:
    • 函数的实现,这部分不能省略,但函数体可以为空。

定义和调用

因为Lambda表达式是一个匿名函数, 因此是没有函数声明的, 直接在程序中进行代码的定义即可, 但是如果只定义匿名函数在程序执行过程中是不会被调用的。

// 匿名函数的定义, 程序执行这个匿名函数是不会被调用的 [](){ qDebug() << "hello, 我是一个lambda表达式..."; }; // 匿名函数的定义+调用: int ret = [](int a) -> int { return a+1; }(100); // 100是传递给匿名函数的参数

在Lambda表达式的捕获列表中也就是 [] 内部添加不同的关键字, 就可以在函数体中使用外部变量了。

// 在匿名函数外部定义变量 int a=100, b=200, c=300; // 调用匿名函数 [](){ // 打印外部变量的值 qDebug() << "a:" << a << ", b: " << b << ", c:" << c; // error, 不能使用任何外部变量 } [&](){ qDebug() << "hello, 我是一个lambda表达式..."; qDebug() << "使用引用的方式传递数据: "; qDebug() << "a+1:" << a++ << ", b+c= " << b+c; }(); // 值拷贝的方式使用外部数据 [=](int m, int n)mutable{ qDebug() << "hello, 我是一个lambda表达式..."; qDebug() << "使用拷贝的方式传递数据: "; // 拷贝的外部数据在函数体内部是只读的 // 如果不添加 mutable 关键字是不能修改这些只读数据的值的 // 添加 mutable 允许修改的数据是拷贝到函数内部的副本, 对外部数据没有影响 qDebug() << "a+1:" << a++ << ", b+c= " << b+c; qDebug() << "m+1: " << ++m << ", n: " << n; }(1, 2)