首页 > 技术文章 > C++ 11 Lambda表达式

vlyf 2019-10-15 09:06 原文

利用Lambda表达式,可以方便的定义和创建匿名函数。

声明Lambda表达式

Lambda表达式完整的声明格式如下:

 [capture list] (params list) mutable exception-> return type { function body }

各项具体含义如下:

  1. capture list:捕获外部变量列表
  2. params list:形参列表
  3. mutable指示符:用来说用是否可以修改捕获的变量
  4. exception:异常设定
  5. return type:返回类型
  6. function body:函数体

 此外,我们还可以省略其中的某些成分来声明“不完整”的Lambda表达式,常见的有以下几种:

序号格式
1 [capture list] (params list) -> return type {function body}
2 [capture list] (params list) {function body}
3 [capture list] {function body}

 

 

 

 

 

其中:

  • 格式1声明了const类型的表达式,这种类型的表达式不能修改捕获列表中的值。
  • 格式2省略了返回值类型,但编译器可以根据以下规则推断出Lambda表达式的返回类型:(1):如果function body中存在return语句,则该Lambda表达式的返回类型由return语句的返回类型确定; (2):如果function body中没有return语句,则返回值为void类型。
  • 格式3中省略了参数列表,类似普通函数中的无参函数。

下面的实例说明了Lambda的一个作用:

 1 #include <iostream>
 2 #include <vector>
 3 #include <string>
 4 #include <algorithm>
 5 #include <fstream>
 6 using namespace std;
 7 
 8 bool isShoter(const string &str1, const string &str2)//要改写的函数
 9 {
10     return str1.size() < str2.size();
11 }
12 
13 void outputWords(vector<string> &v)
14 {
15     for (auto it = v.cbegin(); it != v.cend(); ++it)
16         cout << *it << " ";
17     cout << endl;
18 }
19 
20 void elimDups(vector<string> &v)
21 {
22     outputWords(v);
23 
24     sort(v.begin(), v.end(), isShoter);
25     outputWords(v);
26 
27     auto endUnique = unique(v.begin(), v.end());
28     outputWords(v);
29 
30     v.erase(endUnique, v.end());
31     outputWords(v);
32 }
33 
34 int main(int argc, char *argv[])
35 {
36     ifstream in(argv[1]);
37     if (!in)
38     {
39         cout << "打开文件夹失败!" << endl;
40         exit(1);
41     }
42 
43     vector<string> words;
44     string word;
45     while (in >> word)
46         words.push_back(word);
47     elimDups(words);
48 
49     return 0;
50 }

将isShorter函数改为Lambda表达式形式:

 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 #include <string>
 5 #include <fstream>
 6 
 7 using namespace std;
 8 
 9 void outputWords(vector<string> &v)
10 {
11     for_each(v.cbegin(), v.cend(), [](string &str) { cout << str << ' '; });
12     cout << endl;
13 }
14 
15 void elimDups(vector<string> &v)
16 {
17     outputWords(v);
18     sort(v.begin(), v.end());
19     outputWords(v);
20 
21     auto endUnique = unique(v.begin(), v.end());
22     outputWords(v);
23     v.erase(endUnique, v.end());
24 }
25 
26 void biggies(vector<string> &v, size_t sz)
27 {
28     elimDups(v);
29     stable_sort(v.begin(), v.end(), [](const string &a, const string &b) { return a.size() < b.size(); });//替换isShorter函数
30 
31     auto wc = find_if(v.begin(), v.end(), [sz](const string &s) { return s.size() >= sz; });//另一个Lambda表达式
32     auto count = v.end() - wc;
33     for_each(wc, v.end(), [](const string &s) { cout << s << ' '; });
34     cout << endl;
35 }
36 
37 int main(int argc, char *argv[])
38 {
39     ifstream in(argv[1]);
40     if (!in)
41     {
42         cout << "打开文件夹失败!" << endl;
43         exit(1);
44     }
45 
46     vector<string> words;
47     string word;
48     while (in >> word)
49         words.push_back(word);
50     biggies(words);
51 
52     return 0;
53 }

在C++11之前,我们使用STL的sort函数,需要提供一个谓词函数。如果使用C++11的Lambda表达式,我们只需要传入一个匿名函数即可,方便简洁。

 

推荐阅读