C++11 lambda表达式小结
简介
lambda表达式是一个匿名内联函数,可以定义别的函数体中,其形式如下:
[capture list](parameter list)->return type{funtion body}
从中可以看到,lambda只能使用尾置返回类型;
尾置返回类型放在参数列表后边以->开头,然后再原来放返回类型的地方放一个auto。
结构
lambda不可缺少的部分是捕获列表capture list和函数体funtion body,其他都可以忽略不写。
return type
return type会根据funtion body中的内容来推断,如果只含有一个return 语句,类型就从其推断,否则就是void。如果不是上述情况,就需要自己定义一个返回类型,防止推断为void和期望返回的类型不符合的问题。
parameter list
parameter list需要实参和形参互相匹配,且lambda不能有默认参数,所以两者属于也要相等。
capture list
capture list是lambda所在函数中定义的局部变量,lambda可以对其进行捕获然后进行使用,捕获过程也分为值和引用,使用时看是否需要对捕获的变量进行修改和所捕获的变量是否支持这种操作。
值捕获和引用捕获
值捕获需要变量能被拷贝,比如IO流是不能被拷贝,这就只能用引用。
有时可能需要返回一个lambda,当返回时,此lambda就不能用到引用,否则就会出现函数将返回一个局部变量的引用,这是不合法的。
引用捕获需要对象存在。
变量修改
lambda在捕获的时候就对变量进行了复制(值捕获时),所以希望能借此修改外部变量,应该时用引用。但是如果只需要就地对捕获的变量进行修改并且不想对外部修改的话,就可以在值捕获时在参数列表之后指明mutable关键字。
隐式和显式捕获
显示就是直接写出局部变量,隐式就是不在capture list中写出名字,只写捕获方式,其中 = (代表值捕获), & (代表引用捕获),让编译器自己推断要使用那些变量。
比如:
[ = ](string s1){return s1.size()>=length;} //假设length为一个局部变量,则此时采用值捕获。
两者也可以混搭,这有一个要求:capture list中第一个元素必须为隐式捕获,并且显示和隐式捕获的方式必须不同。
比如:
[ = ,&os](string &s){ os << s << tmp; } //假设tmp为局部变量,采用了值捕获,则只能用显示捕获
捕获列表小结:
| 列表 | 含义 |
|---|---|
| [] | 空捕获列表 |
| [n1,&n2,n3,&n4...] | 以逗号为分隔的捕获列表,显示捕获 |
| [&] | 隐式捕获,lambda中使用的变量全部采用引用捕获 |
| [=] | 隐式捕获,lambda中使用的变量全部采用值捕获 |
| [&,n1,n2] | 混和捕获,n1和n2值捕获,其余为引用捕获 |
| [=,&n1,&n2] | 混和捕获,n1和n2引用捕获,其余为值捕获 |
examples
#include<bits/stdc++.h>
using namespace std;
void elimDups(vector<string>& words) {
sort(words.begin(), words.end());
auto end_unique = unique(words.begin(), words.end());
//for (auto i : words)cout << i << " "; cout << endl;
words.erase(end_unique, words.end());
//for (auto i : words)cout << i << " "; cout << endl;
}
//countwords返回一个计数值,表示有多少个元素长度大于等于sz
int countwords(vector<string>& words, vector<string>::size_type sz) {
elimDups(words);//字典序排序,删除重复元素;
stable_sort(words.begin(), words.end(), [](const string& s1, const string& s2) {return s1.size() < s2.size(); });//长度排序,长度相同也维持字典序
//for (auto i : words)cout << i << " "; cout << endl;
auto it = count_if(words.begin(), words.end(), [sz](const string& s) { return s.size() >= sz; });
return it;
}
int main(void) {
vector<string>words;
string str;
while (cin >> str) {
words.push_back(str);
}
//for (auto i : words)cout << i << " "; cout << endl;
int cnt = countwords(words, 5);//计算有多少个元素长度大于等于5
cout << cnt << endl;
//the quick red fox jumps over the slow red turtle
auto f=[&]()->bool {
while (cnt > 0)cnt--;
if (cnt == 0)return true;
};
cout << f() << endl;//调用lambda改变变量
cout << cnt << endl;
cout << f() << endl;//再调用lambda不再改变变量
cout << cnt << endl;
return 0;
}
input:
the quick red fox jumps over the slow red turtle
output:
3
1
0
1
0
problems
1.为什么需要使用mutable才能进行修改?
lambda在定义时,编译器就会生成一个对应的匿名类,该类会包含所有被捕获的变量作为数据成员初始化,并且该类的operator()默认时const,这就导致无法修改类中的成员函数,加上mutable,即可转换为非const,就可以就地修改了。
C++11 lambda表达式小结的更多相关文章
- C++11 lambda 表达式
C++11 新增了很多特性,lambda 表达式是其中之一,如果你想了解的 C++11 完整特性,建议去这里,这里,这里,还有这里看看.本文作为 5 月的最后一篇博客,将介绍 C++11 的 lamb ...
- C++11 lambda 表达式解析
C++11 新增了很多特性,lambda 表达式是其中之一,如果你想了解的 C++11 完整特性,建议去这里,这里,这里,还有这里看看.本文作为 5 月的最后一篇博客,将介绍 C++11 的 lamb ...
- 详解 C++11 lambda表达式
详解 C++11 lambda表达式 lambda表达式是函数式编程的基础.咱对于函数式编程也没有足够的理解,因此这里不敢胡言乱语,有兴趣的可以自己查找相关资料看下.这里只是介绍C++11中的la ...
- C++11 lambda表达式学习
lambda表达式是函数式编程的基础.咱对于函数式编程也没有足够的理解,因此这里不敢胡言乱语,有兴趣的可以自己查找相关资料看下.这里只是介绍C++11中的lambda表达式自己的认识.这里有参考文档h ...
- C++ 11 Lambda表达式
C++11的一大亮点就是引入了Lambda表达式.利用Lambda表达式,可以方便的定义和创建匿名函数.对于C++这门语言来说来说,“Lambda表达式”或“匿名函数”这些概念听起来好像很深奥,但很多 ...
- C++11 lambda表达式是如何实现的?
lambda表达式是如何实现的呢? 其实是编译器为我们了创建了一个类,这个类重载了(),让我们可以像调用函数一样使用.所以,你写的lambda表达式和真正的实现,是这个样子的: 而对于捕获变量的lam ...
- C++ 11 Lambda表达式、auto、function、bind、final、override
接触了cocos2dx 3.0,就必须得看C++ 11了.有分享过帖子:[转帖]漫话C++0x(四) —- function, bind和lambda.其实最后的Lambda没太怎么看懂. 看不懂没关 ...
- c++11——lambda表达式
lambda表达式 函数式编程的一个语法,有如下优点: (1)声明式编程风格:就地匿名定义目标函数或函数对象,不需要额外写一个命名函数或者函数对象.以更直接的方式写程序,好的可读性和可维护性. (2) ...
- C++11 Lambda表达式简单解析
C++11 新增了非常多特性,lambda 表达式是当中之中的一个.假设你想了解的 C++11 完整特性, 建议去http://www.open-std.org/看看新标准! 非常多语言都提供了 la ...
随机推荐
- 批处理文件将多台连接的手机安装同一个APP
:adb devices > C:\Users\aaminaxu\Desktop\a.txt :1.首先获取连接到电脑的手机的设备信息将其保存到C盘的a.txt文件中::2.将保存的txt文件中 ...
- python string_1
quote :http://www.runoob.com/python/python-strings.html #coding:utf-8 s1="http://www.jnshu.com/ ...
- 【HANA系列】SAP HANA STUDIO客户端升级更新
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA STUDIO客 ...
- keras recall
# accuracy, fmeasure, precision,recall def mcor(y_true, y_pred): y_pred_pos = K.round(K.clip(y_pred, ...
- jenkins初级使用篇
1.jenkins的初级使用 1.1 介绍 创建一个项目 可以看到当前登陆用户及用户权限 可以查看到所有构建过的项目的历史 系统管理 My Views:视图功能,我们可以自己创建一个自己的视图 系统管 ...
- 【Go语言】map在goroutine通信中的使用问题
简介 本篇文章的主要内容是解决go语言map在使用中遇到的两个问题,对于初学者是不可避免的坑 一.cannot assign to struct field 当map中存在struct类型的成员,如果 ...
- 使用screen管理后台程序
我们常需要SSH 或者telent 远程登录到Linux 服务器,经常运行一些需要很长时间才能完成的任务,在此期间不能关掉窗口或者断开连接,否则这个任务就会被杀掉,一切半途而废了.这时,我们可以用sc ...
- JSON.toJSONString时保留null值
QuoteFieldNames———-输出key时是否使用双引号,默认为true WriteMapNullValue——–是否输出值为null的字段,默认为false WriteNullNumberA ...
- C语言第十一周作业
这个作业属于哪个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/computer-scienceclass3-2018/ ...
- Oracle 查看一个数据库实例下面所有的表大小
1. 因为 oracle有一些 lob字段 在user_extents 里面取出来的结果不是表名, 所以需要与user_lobs 表做关联查询才可以 本来想通过 关联查询来实现, 发现字表查询更简单 ...