lambda表达式
在c++11中新增了lambda表达式,由于自己对这一部分比较生疏,所以在这里稍稍总结一些lambda表达式的用法以便以后回顾。在引入lambda表达式之前,先来看一个简单的例子,定义一个vector
并打印其中的数值。
vector<int> V;
for(int i=0;i<10;i++)V.push_back(i);
struct{
void operator()(int val){
cout<<val<<' ';
}
}print;
for_each(V.begin(),V.end(),print);
虽然仅仅实现了一个打印的功能,但是却写了多行代码完成这个简单的功能,这显然是不’优雅’的,那么有没有一种更加简介的写法呢?那就是lambda表达式了,lambda表达式是一种匿名函数,所以无需绑定函数名,一般其结构如下:
[捕获参数列表](参数)[函数体]
具体捕获参数列表是什么会在之后介绍,先来看一下参数和函数体,可以发现这其实和一般的函数定义非常相似,唯一的不同就是没有绑定函数名。下面通过一个实例演示一下lambda的强大之处,同样实现打印vector
的功能:
vector<int> V;
for(int i=0;i<10;i++)V.push_back(i);
for_each(V.begin(),V.end(),[](int val){
cout<<val<<' ';
});
显然,这样的写法比原来的定义结构体要简洁的多。简洁性是lambda表达式的一个特点,但是除了这个特性lambda表达式还有一个更强大的功能,就是捕获参数列表。在c++中一般变量的作用域都在函数体内部,而定义在外部的函数显然无法获取到函数内部的局部变量,那么假设真的有这样的一个场景需要一个外部函数获取内部变量呢?这时就可以使用lambda表达式了。那么先来看一看捕获参数列表怎么使用:
捕获形式 | 说明 |
---|---|
[] | 不捕获任何外部变量 |
[变量名, …] | 默认以值(&引用)得形式捕获指定的多个外部变量(用逗号分隔) |
[this] | 以值的形式捕获this指针 |
[=] | 以值的形式捕获所有外部变量 |
[&] | 以引用形式捕获所有外部变量 |
[=, &x] | 变量x以引用形式捕获,其余变量以传值形式捕获 |
[&, x] | 变量x以值的形式捕获,其余变量以引用形式捕获 |
下面看一个捕获参数的简单实例:
vector<int> V;
for(int i=0;i<10;i++)V.push_back(i);
int m = 10;
for_each(V.begin(),V.end(),[](int val){
cout<<val*10<<' ';
});
定义一个变量m
,将所有vector
中的变量乘以m
再打印,显然使用一般的函数无法直接调用参数m
,而需传递参数,但是lambda可以方便的捕获定义域内的变量。
引用传递
函数的传递方式一般有三种,按值传递、引用传递和指针传递。三种中引用传递的执行效率最高,因为按值传递需要对原始数据进行拷贝有时间空间的消耗,而指针传递有寻址的时间消耗,所以相对引用传递的执行效率较好。一般&
会搭配const
来使用。下面演示一个小例子:
// 增加const之后无法对数值修改,更加安全
int add(const int &a,const int &b){
return a+b;
}
vector 和 bitset
在实际应用中遇到一个需要使用布尔类型数组的场景,一开始使用了vector<bool>
但是效率并不是很高,下面来详细解释一下为什么会有效率问题。在c++中bool
类型和char
类型都是一字节,显然bool
用一个字节存储一比特的数据有些浪费,所以在vector<bool>
存储中为了进行优化,c++将一个字节存储了8个bool
变量,这样做的确极大的降低了存储空间,但是又带了一个新的问题,无法随机读取。因为在c++的运行中,所有的操作都是以字节为单位,所以无法直接读取vector<bool>
中的变量,所以会对查找速度有很大的影响。简单来说vector<bool>
对空间进行了优化,但是不可避免的损失了一些效率,这是一种典型的空间换时间的操作。
那么,如果在实际开发中遇到对随机存取要求很高的场景有没有什么解决方案呢,其中最简单的方案就是使用bitset
。
#include <bitset>
int main() {
// 用长整型初始化一个bitset
const bitset<12> mask(2730ul);
cout << "mask = " << mask << endl;
// mask = 101010101010
}