C++Lambda函数

Lambda函数

概念

  • Lambda表达式用于创建和定义匿名函数
  • 匿名函数:顾名思义也就是可以没有名字的函数可以看成是一个内联函数,在python、C#等语言都有这种函数表达式的实现。
  • 通常适用于创建一些代码量少的函数以及在当前所处函数中调用次数少的函数

声明Lambda表达式

1
2
3
4
//Lambda表达式的完整声明
[capture list](param list) mutable exception->return_type{
funtion body
};
  • capture list捕获外部变量列表

    Lambda捕获列表:

    • []空捕获列表,lambda不能使用所在函数中的变量
    • [=]函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this指针),并且使用值传递的方式传递(编译器自动做的)
    • [&]函数体内可以使用Lambda所在作用范围内所有可见的局部变量(包括Lambda所在类的this指针),并且使用引用传递方式传递(编译器自动做的)
    • [this]函数体内可以使用Lambda所在类中的所有成员变量
    • [x]将外部变量x按值进行传递,不能修改x值,可以添加mutable修饰符允许修改
    • [&x]将外部变量x按引用方式进行传递
    • [=,&x,&y]除外部变量x和y按引用方式传递,其他参数都按值传递方式传递
    • [&,x,y]除外部变量x和y按值进行传递外,其他参数都按引用方式进行传递
  • param list匿名函数形参列表

  • mutable(可选):是一种修饰符,用来声明Lambda函数体能否修改以值传递的捕获变量的值(值传递是会在Lambda体中复制形参值形成新对象,所以在Lambda的操作并不会修改Lambda外部变量的值,以引用形式传递的可以),当需要Lambda函数体能够修改以值传递的捕获变量值,需要在声明时加上该规范

  • exception(可选):**异常规范(设定)**,可以使用noexcept或者throw()设定函数不抛出异常

  • return_type返回类型

  • function body函数体

一些格式

Lambda表达式是可以省略某些成分来进行声明,常用的有如下几种:

  1. **声明了const类型的表达式(没有加mutable修饰符,默认都是const类型)**,这种类型的表达式不能修改捕获列表中的值

    1
    [capture list](param list)->return_type {function body};
  2. 省略了返回值类型,编译器会根据Lambda体自动推导返回值类型,如果有返回值则编译器会自动推导返回值类型,如果没有返回值则默认为void类型

    1
    [capture list](param list){function body};
  3. 省略了参数列表,则这个函数就是无参函数

    1
    [capture list]{function body};

悬垂引用:

  • 若以引用隐式或显式捕获非引用实体,而在该实体的生存期结束之后调用lambda对象的函数调用运算符,则发生未定义行为。C++ 的闭包并不延长被捕获的引用的生存期。这同样适用于被捕获的this指针所指向的对象的生存期
  • 简单来说就是在Lambda表达式捕获的实体生命周期结束后再调用Lambda函数则会发生找不到对应实体,导致发生未定义错误

基本使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <functional>


int main (int argc, char *argv[]) {
int c=2;
auto foo=[&](int a,int b)->void{
std::cout<<a+b+c<<std::endl;
};
//结合function的使用案例
std::function<void(int,int)>f=[=](int a,int b){
std::cout<<a+b+c<<std::endl;
};
f(1,2);
foo(1,2);
return 0;
}

C++Lambda函数
https://moonfordream.github.io/posts/C-Lambda函数/
作者
Moon
发布于
2024年7月25日
许可协议