一个lambda表达式表示一个可调用的代码单元。我们可以将其理解为一个未命名的内联函数。与任何函数类似,一个lambda具有一个返回类型、一个参数列表和一个函数,但与函数不同,lambda可能定义在函数内部。一个lambda表达式具有如下形式:
[capture list](parameter list)->return type {function body}
其中,capture list(捕获列表)是一个lambda所在函数中定义的局部变量的列表(通常为空);
return type, parameter list和function body与任何普通函数一样,分别表示返回类型、参数列表和函数体。
但与普通函数不同,lambda必须使用尾置返回(参见6.3.3节,第206页)来指定返回类型。
注:以上是《C++ Primer》第5版中的第10.3.2节的说明。
int nCount = 10;
QString str = QStringLiteral("大漠孤烟直长河落日圆");
QString str2 = QStringLiteral("use lambda expression");
connect(ui->pushButton, &QPushButton::clicked, [=](bool checked)
{
qDebug() << "nCount=" << nCount << "str=" << str;
qDebug() << "checked==" << checked;
});
connect(ui->pushButton_2, &QPushButton::clicked, [=]()
{
qDebug() << "nCount=2==" << nCount << "str2=" << str2;
});
与普通函数最大的区别是,除了可以使用参数以外,Lambda函数还可以通过捕获列表访问一些上下文中的数据。具体地,捕捉列表描述了上下文中哪些数据可以被Lambda使用,以及使用方式(以值传递的方式或引用传递的方式)。语法上,在“[]”包括起来的是捕捉列表,捕捉列表由多个捕捉项组成,并以逗号分隔。捕捉列表有以下几种形式:
1.[var]表示值传递方式捕捉变量var;
2.[=]表示值传递方式捕捉所有父作用域的变量(包括this);
3.[&var]表示引用传递捕捉变量var;
4.[&]表示引用传递方式捕捉所有父作用域的变量(包括this);
5.[this]表示值传递方式捕捉当前的this指针。
上面提到了一个父作用域,也就是包含Lambda函数的语句块,说通俗点就是包含Lambda的“{}”代码块。上面的捕捉列表还可以进行组合,例如:
1.[=,&a,&b]表示以引用传递的方式捕捉变量a和b,以值传递方式捕捉其它所有变量;
2.[&,a,this]表示以值传递的方式捕捉变量a和this,引用传递方式捕捉其它所有变量。
不过值得注意的是,捕捉列表不允许变量重复传递。
下面一些例子就是典型的重复,会导致编译时期的错误。例如:
3.[=,a]这里已经以值传递方式捕捉了所有变量,但是重复捕捉a了,会报错的;
4.[&,&this]这里&已经以引用传递方式捕捉了所有变量,再捕捉this也是一种重复。