Lambda表达式

C++11中的Lambda表达式用于定义匿名的函数对象,以简化编程工作。首先看一下Lambda表达式的基本构成:

分为四个部分:[局部变量捕获列表]、(函数参数)、函数额外属性设置opt、函数返回值->retype、{函数主体}

[capture](parameters) opt ->retType

{

……;

}

局部变量引入方式

[ ],标识一个Lambda的开始。由于lambda表达式可以定义在某一个函数体A里边,所以lambda表达式有可能会去访问A函数中的局部变量。中括号里边内容是描述了在lambda表达式里边可以使用的外部局部变量的列表:

[]

    表示lambda表达式不能访问外部函数体的任何局部变量

[a]

    在函数体内部使用值传递的方式访问a变量

[&b]

    在函数体内部使用引用传递的方式访问b变量

[=]

    函数外的所有局部变量都通过值传递的方式使用, 函数体内使用的是副本

[&]

    引用的方式使用lambda表达式外部的所有变量

[=, &foo]

    foo使用引用方式, 其余是值传递的方式

[&,foo]

    foo使用值传递方式, 其余是引用传递的方式

[this]

在函数内部可以使用类的成员函数和成员变量,=和&形式也都会默认引入

由于引用方式捕获对象会有局部变量释放了而lambda函数还没有被调用的情况。如果执行lambda函数那么引用传递方式捕获进来的局部变量的值不可预知。

所以在无特殊情况下建议使用[=](){}的形式

函数参数

(params)表示lambda函数对象接收的参数,类似于函数定义中的小括号表示函数接收的参数类型和个数。参数可以通过按值(如:(int a,int b))和按引用(如:(int &a,int &b))两种方式进行传递。函数参数部分可以省略,省略后相当于无参的函数。

选项Opt

Opt 部分是可选项,最常用的是mutable声明,这部分可以省略。外部函数局部变量通过值传递引进来时,其默认是const,所以不能修改这个局部变量的拷贝,加上mutable就可以

  

  int a = 10 ;

    [=]()

    {

        a=20;//编译报错,a引进来是const

}

    [=]()mutable

    {

        a=20;//编译成功

};

函数返回值 ->retType

->retType,标识lambda函数返回值的类型。这部分可以省略,但是省略了并不代表函数没有返回值编译器会自动根据函数体内的return语句判断返回值类型,但是如果有多条return语句,而且返回的类型都不一样,编译会报错,如:

  
   [=]()mutable
    {

        int b = 20;

        float c = 30.0;

        if(a>0)

            return b;

        else

            return c;//编译报错,两条return语句返回类型不一致

    };

函数主体{}

     {},标识函数的实现,这部分不能省略,但函数体可以为空。

槽函数使用Lambda表达式

以QPushButton点击事件为例:

  

  connect(btn,&QPushButton::clicked,[=](){

        qDebug()<<"Clicked";

});

这里可以看出使用Lambda表达式作为槽的时候不需要填入信号的接收者。当点击按钮的时候,clicked信号被触发,lambda表达式也会直接运行。当然lambda表达式还可以指定函数参数,这样也就能够接收到信号函数传递过来的参数了。

由于lambda表达式比我们自己自定义槽函数要方便而且灵活得多,所以在实现槽函数的时候优先考虑使用Lambda表达式。一般我们的使用习惯也是lambda表达式外部函数的局部变量全部通过值传递捕获进来,也就是:

[=](){  }的形式

你可能感兴趣的:(Qt从0到1,开发语言,qt,c++)