C++中有 五种可调用对象:
1. 函数
2. 函数指针
3. lambda表达式
4. 重载了函数调用运算符的类
5. bind创建的对象
函数不能定义在另一个函数内, 但是 lambda表达式可以定义在函数内。
一个lambda表达式 表示一个可调用的代码单元,可理解为 一个未命名的内联函数。一个lambda表达式具有一个返回类型、一个参数列表 和 一个函数体。表达式形式如下:
[capture list ] ( parameter list) -> return type { function body }
capture list : 捕获列表
return type : 返回类型
parameter list:参数列表
function body: 函数体
捕获规则:
捕获规则是指Lambda表达式捕获外部变量的方式。C++11标准规定了三种捕获方式:
- 值捕获(Capture by value):使用
[=]
表示 以值方式 捕获所有的外部变量,Lambda表达式中的外部变量会被复制一份,修改Lambda表达式中的变量不会影响外部变量。- 引用捕获(Capture by reference):使用
[&]
表示 以引用方式 捕获所有的外部变量,Lambda表达式中的外部变量是外部变量的引用,修改Lambda表达式中的变量会影响外部变量。[this]
表示 以引用方式 捕获当前对象的指针,可以在Lambda表达式中访问当前对象的成员变量和成员函数。- 显式捕获(Explicit capture):使用
[var]
表示捕获外部变量var
,使用[&var]
表示捕获外部变量var
的引用,使用[=var]
表示捕获外部变量var
的副本,使用[&, var]
表示以引用方式捕获所有的外部变量并捕获外部变量var
的副本,使用[=, &var]
表示以值方式捕获所有的外部变量并捕获外部变量var
的引用。
Lambda表达式可以使用任意的组合方式,例如[this, a, b](int c){}
表示以引用方式捕获当前对象的指针,并以值方式捕获变量a
和b
,同时接受一个整型参数c
。
捕获的时候,这个外部变量,外部的范围是哪些范围?
在Lambda表达式中捕获的外部变量,指的是 Lambda表达式定义的位置所在 的 外部作用域中 的变量。具体来说,Lambda表达式可以捕获以下外部变量:
this
捕获了当前对象的指针,则Lambda表达式可以访问当前对象的所有成员变量。需要注意的是,Lambda表达式只能捕获定义在Lambda表达式所在的外部作用域中的变量,不能捕获在Lambda表达式内部或者其他作用域中定义的变量。
如果需要在Lambda表达式中使用其他作用域中的变量,可以通过函数参数的方式传递进来。
lambda 必须使用 尾置返回 (比如 [ ](int a)-> int { ...... })来指定返回类型。 如果 忽略返回类型,lambda根据函数体中的代码推断出返回类型。
例如:
auto compare = [](const int a, const int b){ return a > b;}
在Lambda表达式的参数列表中,可以指定函数的参数,也可以使用默认参数,例如([](){})
表示一个不带参数的Lambda表达式,([](int a){})
表示一个带有一个整型参数的Lambda表达式。
在Lambda表达式的函数体中,可以编写任意有效的C++代码,包括语句、表达式、控制结构等。Lambda表达式可以返回一个值,也可以不返回任何值。
调用方式与普通函数的调用方式相同,都是使用调用运算符() :
示例1:
#include
#include
#include
#include
using namespace std;
int main()
{
auto compare = [](const int a, const int b) {return a > b; };
cout << "3 与 7的对比结果:"<
运行结果是:
示例2:
sort函数,默认是从小到大排序,自定义按照string的大小进行排序
#include
#include
#include
#include
using namespace std;
int main()
{
vector mystring = {"a","egg","elephant","piggy","monkey","yellow","ahelkh","walawalawala"};
sort(mystring.begin(), mystring.end(), [](const string a, const string b) {return a.size() > b.size(); });
cout << "sort排序后的结果是:";
for (auto mem:mystring)
{
cout << " " << mem;
}
cout << endl;
system("pause");
return 0;
}
运行结果:
lambda以一对 [ ] 开始,可以在其中提供一个以逗号分隔的名字列表 , 这些名字都是 它所在函数中定义的。
示例1:
#include
#include
#include
#include
using namespace std;
int main()
{
//使用捕获列表
//
string a = "hlloy high";
string b = "what?";
auto compare= [a,b](const string c)
{
return c.size() > a.size() && c.size() >b.size();
};
cout << compare("WoWwwww you get one goald") << endl;
system("pause");
return 0;
}
运行结果是:
示例2:
#include
#include
#include
#include
using namespace std;
int main()
{
vector mystring = {"a","egg","elephant","piggy","monkey","yellow","ahelkh","walawalawala"};
//找到第一个大于6的字符串
int sz = 6;
auto wx = find_if(mystring.begin(), mystring.end(), [sz](const string a) {return a.size() > sz; });
cout <<"第一个大于 sz 大小的字符串是:"<< *wx << endl;
system("pause");
return 0;
}
执行结果是: