C++ 11 匿名函数Lambda表达式

C++ 11匿名函数Lambda表达式

格式

语法

[ capture-list ] ( params ) mutable exception attribute -> ret { body }

[ capture-list ] ( params ) -> ret {body }

[ capture-list ] ( params ) { body }

[ capture-list ] { body }

参数说明

mutable 允许body修改按复制捕获的参数,及调用其非const成员函数

exception为调用lambda提供异常规定或noexcept子句

attribute 为调用lambda提供属性规定

capture-list捕获参数列表

[a, &b] 其中a以const值捕获而b以引用捕获。

[this] 以值捕获this指针

[&] 以引用捕获所有使用的自动变量,及以引用捕获当前对象,若它存在

[=] 以值捕获所有使用的自动变量,及以引用捕获当前对象,若它存在

[] 无捕获

params 参数列表,参数类型可以用auto代表泛型

ret 返回类型。若不写,则为函数的return语句所隐喻(或若函数不返回任何值则为void)

body 函数体

 

例:

    auto f = [](auto a,auto b){cout<<a<<" "<<b<<endl; };

    f(3, 4.5);

    f(5.5,"abc");

 

    int n= 10,m = 20;

    auto f2 = [n, &m](){

        //n++;//语法错误,nconst类型不可改变

        cout<<n<<" "<<m<<endl;;

        ++m;

    };

    f2();

    cout<<n<<" "<<m<<" "<<endl;

 

 

 

说明,防止崩溃

Lambda表达式本身是一个对象,重载了()运算符,operator()。

以值捕获的参数对像内会有一个副本,是const类型,如果需要改变这个值需要参数列表后加上mutable关键字。

以引用捕获的参数,对象内会存储一个指针,类型为T *const p,指针指向捕获前的参数,所以引用方式捕获的参数,Lambda内可以改变捕获参数的值。

 

当通过引用捕获参数时,要确保Lambda表达式执行时,参数内存没有被释放,否容易导致崩溃。特别是以引用的方式捕获栈上的参数,结束完赋值后很有可能已经离开了栈空间。

例:

struct MyStruct

{

    function<void(void)>f;

};

 

void f(MyStruct *pStruct)

{

    int a= 10;

    pStruct->f=[&a]() {//错误,当 f执行完后a的内存被释放了,容易崩溃

        a=a*a;

    };

}

 

 

 

Lambda表达式本身也是一个对象,在执行Lambda表达式时要防止lambda表达式对象自己被释放,lambda表达式对象释放后,捕获的参数也被释放了。

struct B

{

    function<void(void)>f;

};

 

B*f2()

{

    B*b=new B;

    inta= 10;

    b->f=[b,&a]() {

        delete b;//错误,b对象释放会将仿函数对象一起释放调。

        a= 11;//程序崩坏Lambda表达式已经被释放掉了,存储a的地址参数被释放了。

    };

    return b;

}

你可能感兴趣的:(编程语言杂记,C,11,蓝天日记,lambda崩溃)