lambda表达式解析

lambda表达式解析

什么是lambda表达式

lambda表达式是一个可调用的代码单元,可以将其理解为一个未命名的内联函数。

lambda表达式形式:

[捕获列表](参数列表)-> return type{函数体}

其中参数列表和return type可以省略:

auto f=[]{return 42;};

我们经常在排序中使用:

1
2
3
4
5
vector<string> words={"aa","bbbb","ccccc"};
stable_sort(words.begin(),words.end(),[](const string &a,const string &b){return a.size()<b.size();});

return 0;
}

初步分析

我们借助c++ insight工具对其实现原理进行分析

1
2
3
4
5
6
7
8
#include <cstdio>
#include<string>
using namespace std;

int main()
{
auto fun=[](string a,string b){return a.size()<b.size() ;};
}

被编译器转换为:

编译器会将lambda函数转成一个类:class __lambda_7_12,并inline的重载操作符函数

using retType_7_12 = bool (*)(string, string);

这一行创建了一个名为retType_7_12的类型别名。该别名表示一个指向接受两个string参数并返回bool的函数的指针。using关键字用于为更好的代码可读性和可维护性定义此类类型别名

实际上fun是一个对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <cstdio>
#include<string>
using namespace std;

int main()
{

class __lambda_7_12
{
public:
inline bool operator()(std::basic_string<char> a, std::basic_string<char> b) const
{
return a.size() < b.size();
}

using retType_7_12 = bool (*)(string, string);
inline constexpr operator retType_7_12 () const noexcept
{
return __invoke;
};

private:
static inline bool __invoke(std::basic_string<char> a, std::basic_string<char> b)
{
return __lambda_7_12{}.operator()(a, b);
}


};

__lambda_7_12 fun = __lambda_7_12{};
return 0;
}

使用捕获列表

Lambda 表达式可以使用上下文的变量

下面的函数可以用于输出长度大于sz的字符串(c++ primer 349)

1
2
3
4
5
6
void bigger(vector<string> &words,vector<string>::size_type sz,ostream &os =cout){
stable_sort(words.begin(),words.end());
auto bigit=find_if(words.begin(),words.end(),[&sz](const string & a){return a.size()>sz;});
for_each(bigit,words.end(),[&os](const string &s){os<<s<<" ";});
os<<endl;
}

值捕获