如何在C++ 11 中使用Lambda 表达式
Lambda
简介
当一个函数需要将另一个函数用作参数时,可以使用
#include <stdlib.h>
#include <stdio.h>
static int intcompare(const void *p1, const void *p2)
{
int i = *((int *)p1);
int j = *((int *)p2);
return (i < j) ;
}
int main()
{
int a[10] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
qsort((void *)a, 10, sizeof (int), intcompare);
for (int i = 0; i < 10; i++) { printf("%d ", a[i]); }
printf("\n");
return 0;
}
清单
清单
- 比较函数需要单独声明。这增加了将错误的比较函数传递给
qsort() 操作的风险。 - 比较函数接受
void * 参数,因此缺失了某种程度的类型检查。 - 比较函数看不到任何局部作用的变量。因此,如果存在其他影响排序的因素,必须在更大范围内声明。
清单
#include <algorithm>
int main()
{
int a[10] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
std::sort( a, &a[10], [](int x, int y){ return x < y; } );
for(int i=0; i<10; i++) { printf("%i ", a[i]); }
printf("\n");
return 0;
}
清单
Lambda 表达式的基本语法
[](int x, int y){ return x < y ; }
清单
如果我们将
如果
auto foo(...) -> T { ... }
对于
[] (...) -> T { ... }
将Lambda 传递到函数指针
std::function<void(int)>
清单
清单
void scan( int* a, int length, std::function<void(int)> process )
{
for(int i=0; i<length; i++)
{
process(a[i]);
}
}
清单
清单
void f(int);
int a[10];
...
scan(a, 10, f);
scan(a, 10, [](int k)->void { ... } );
清单
Lambda 表达式中的变量捕获
到目前为止,我们对
假设我们需要使用函数
在清单
#include <algorithm>
void scan( int* a, int length, std::function<void(int)> process)
{
for(int i=0; i<length; i++) {
process(a[i]);
}
}
int main()
{
int a[10] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
int threshold = 5;
scan(a, 10,
[threshold](int v)
{ if (v>threshold) { printf("%i ", v); } }
);
printf("\n");
return 0; }
清单
有一个简写形式
scan(a, 10, [=](int v) { if (v>threshold) { printf("%i ", v); } });
清单
注:通过值捕获变量意味着生成局部副本。如果有多个局部变量,全部捕获可能会导致
但有些情况下,我们希望修改捕获的变量。例如,假设我们要计算最大值并将其存储在变量
#include <algorithm>
void scan(int * a, int length, std::function<void (int)> func)
{
for(int i=0; i<length; i++) {
func(a[i]);
}
}
int main()
{
int a[10] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
int threshold = 5;
int max =0;
std::sort( a, &a[10], [](int x, int y){return (x < y);});
scan(a, 10,
[threshold,&max](int v) { if (v>max) {max = v;}
if (v>threshold) { printf("%i ", v); } });
printf("\n");
printf("Max = %i\n",max);
return 0;
}
清单
同样,也有一个简写形式
Lambda 表达式、函数对象和函子
虽然
class compare_ints {
public:
compare_ints(int j, int k ) : l(j), r(k) { }
bool operator()() { return l < r; }
private:
int l, r; };
清单
您可以创建一个
compare_ints comp(j, k);
bool less_than = comp();
也可以动态创建一个临时对象,然后直接使用:
bool less_than = compare_ints(j, k)();
使用
auto comp = [](int j, int k) { return j < k; };
bool less_than = comp(l,r);
清单
在清单
您也可以动态执行此操作:
bool less_than = [l,r]() { return l < r; }();
总结
显然,与