第十七章、C++11的新特性
1. Lambda 表达式
lambda表达式(又叫匿名函数),是C++11标准后新增加的用来创建并返回一个函数的一个表达式。它允许程序在运行时创建函数并返回。
lambda表达式用于在需要的地方创建函数并作为表达式返回,避免在其他地方定义在此调用,可以使程序更易于理解。
语法
捕获列表-> 返回类型 { 函数体 }
说明
- 捕获列表决定外部变量如何被 lambda 表达式使用(值捕获、引用捕获等)。
- 形式参数列表 同普通函数的形式参数列表一样,是用来定义接收数据的形参变量的列表。
- ->返回类型 是此函数的返回类型,可省略。如省略则由 return 后的表达式自动推导得到。
捕获列表的写法
写法
说明
[]不使用外部的变量。
[&]引用使用外部的变量(可修改)。
[=]只读使用外部的变量(不可修改)。
[=,&y]混合使用外部的变量。
示例
向 copy_if 模版函数中传递 lambda 表达式创建的函数。
// filename: lambda.cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 如果是val为负数则返回 true
bool is_negative(const int & val) {
return val < 0;
}
int main(int argc, char * argv[]) {
std::vector<int> v{3, -4, 2, -8, 15, 267};
std::vector<int> v_nega1; // 存放负数的容器
std::vector<int> v_nega2;
// 打印 v
for(auto val: v)
cout << val << " ";
cout << endl;
// 使用 is_negative 函数筛选出所有的负数
copy_if(v.begin(),
v.end(),
back_inserter(v_nega1), // 末尾插入
is_negative);
// 打印 v_nega1;
cout << "筛选出来负数有:" << endl;
for(auto val: v_nega1)
cout << val << " ";
cout << endl;
// 使用 lambda 表达式 筛选出所有的负数
copy_if(v.begin(),
v.end(),
back_inserter(v_nega2), // 末尾插入
[](const int &val)->bool{return val < 0;});
// 打印 v_nega2;
cout << "筛选出来负数有:" << endl;
for(auto val: v_nega2)
cout << val << " ";
cout << endl;
return 0;
}
编译和运行结果如下
weimz@mzstudio:~$ g++ -o lambda lambda.cpp
weimz@mzstudio:~$ ./lambda
3 -4 2 -8 15 267
筛选出来负数有:
-4 -8
筛选出来负数有:
-4 -8
示例2
在 Lambda 表达式内使用外部的变量。
// filename: lambda2.cpp
#include <iostream>
#include <algorithm>
using namespace std;
int main(int argc, char * argv[]) {
int x = 100;
int y = 200;
auto f1 = [=, &y](int a, int b) {
cout << x + a + b + y << endl;
y = 6666;
return x;
};
cout << f1(10, 20) << endl;
cout << "x:" << x << endl;
cout << "y:" << y << endl;
return 0;
}
编译和运行结果如下:
weimz@mzstudio:~$ g++ -o lambda2 lambda2.cpp
weimz@mzstudio:~$ ./lambda2
330
100
x:100
y:6666
可见通过捕获列表 [=,&y] 在 lambda 表达式内可以使用 x 和 y 这两个外部的变量,并可以在 lambda 表达式内修改 y 这个变量。
练习
将下列数组按绝对值排序。
std::vector<int> v{3, -4, 2, -8, 15, 26;
按绝对值升序排序结果。
2, 3, -4, -8, 15, 26;