C++11前的可调用对象有函数指针,函数对象(仿函数)C++11增加了lambda表达式。
lambda表达式的格式
[]()mutable->return type{};
//[]是捕捉列表用来捕获上下文的变量供lambda表达式使用,[]不能省略,它是编译器识别lambda的标识
//()和普通函数的括号一样用来声明形参列表,没有参数时可以省略
//mutable:默认情况下lambda函数是一个const函数,使用mutable可以取消其常性,加上了mutable就不能省略参数列表
//->return type :在这个位置来指明返回类型,可以省略让编译器自行推导,不返回任何数据时也可省略
//{}:大括号里面就是lambda表达式要执行的语句了,在这里可以操作传入的参数变量和捕获的变量
int add(int a, int b)
{
return a + b;
}
//两个实现加法的调用对象,第一个是常规的函数,第二个就是lambda,这里[]不捕获任何lambda当前作用域中的变量
//接受两个整形参数,两个参数之和,返回类型可以写上 [](int a,int b)->int{return a+b;},也可以省略,编译器自行推导。
int main ()
{
cout << add(5, 6) << endl;
auto f1 = [](int a, int b) {return a + b; };
cout << f1(5, 7) << endl;
return 0;
}
对捕获列表的详细说明
(1) []中可以指定要捕获的变量名,可以是值方式捕获,就是值拷贝一份指定变量,引用方式捕获…
(2) []可以捕获多个变量,变量间用逗号隔开。
(3) [=] 这种形式就是以值方式捕获所有的变量。
(4) [&] 就是以引用的方式捕获所有变量。
(5) [=,&a,&b]这里是以引用方式捕获a,b 变量用值方式捕获其他的所有变量。 [&,a]以值方式捕获a ,以引用方式捕获其他所有变量。
(6) 不能重复捕获,比如[=,&a,b]这里是值方式捕获b, =又说明除了a是引用捕获外,其他的变量值捕获,重复说明捕获,会报错。
int main()
{
int b = 1, c = 4;
double d = 3.14;
int a = 5; //可以捕获lambda同一语句块中的变量
auto f1 = [a] {cout << a << endl; }; //值方式捕获
f1();
auto f2 = [&a] {a += 5; }; //引用方式捕获
f2();
cout << a << endl; //10
auto f3 = [=] {cout << a + b + c << endl;//值方式捕获所有变量
cout << d << endl;
};
f3();
auto f4 = [&] {int tem = a;
a = b;
b=tem; }; //引用方式捕获所有变量
f4();
cout << a << " " << b << endl;
auto f5 = [=, &d] {cout << b - a << endl; d *= 2; }; //引用捕获d 值方式捕获其余变量
f5();
cout << d << endl;
return 0;
}
lambda表达式就像是无名函数一样,将其和auto搭配使用,或者作为模板参数传入,sort中就可以把传入仿函数改为传入lambda表达式。
以前我们对自定义数据类型的一组元素用sort进行排序需要传入仿函数控制比较逻辑,对不同的自定义数据类型进行排序都要分别写一个类在类中重载()写出仿函数。这样给编程者带来了极大的不便,lambda表达式则十分方便。下面分别用仿函数和lambda表达式作为控制方法来排序一组数据。
struct Book
{
string name;
double price;
int num;
};
struct compare
{
bool operator()(const Book& a, const Book& b)
{
if (a.price > b.price)
return true;
else if (a.price == b.price)
{
if (a.num > b.num)
return true;
else
return false;
}
else
return false;
}
};
int main()
{
Book arr[] = { {"C++ primer",65.5,20},{"现代操作系统",49.8,15},{"Linux 私房菜",49.8,25},
{"数据结构",30.5,12},{"C和指针",35.9,24},{"Effective C++",36.6,17}};
//sort(arr, arr + sizeof(arr) / sizeof(arr[0]), compare()); //按价格降序排列,价格相同时按数量降序排
sort(arr, arr + sizeof(arr) / sizeof(arr[0]), [](const Book& a, const Book& b)->bool {
if (a.price > b.price) //改用lambda实现同样的功能
return true;
else if (a.price == b.price)
{
if (a.num > b.num)
return true;
else
return false;
}
else
return false; });
for (auto e : arr)
cout << e.name << " " << e.price << " " << e.num << endl;
return 0;
}



