详解 C++11 lambda表达式
lambda表达式是函数式编程的基础。咱对于函数式编程也没有足够的理解,因此这里不敢胡言乱语,有兴趣的可以自己查找相关资料看下。这里只是介绍C++11中的lambda表达式以及与此相关的闭包(closure)。
其次,给出两个例子,可以看出lambda表达式的写法
[](int x, int y) { return x + y; } [](int x, int y) -> int { int z = x + y; return z + x; } //表明返回值类型是int型
也就是说,一个lambda表达式很类似于普通的函数定义的写法,区别在于三点,一是没有函数名(你也可以认为函数名是[]),二是这个函数没有普通函数那样的返回值类型,返回值类型的写法在第2行,即在参数列表与函数定义之间以箭头写明,三是在参数列表之前有一个[] (其实这里还可能有更多的形式,后面会说)
第三,lambda表达式的标准形式是什么?
如下。这里先只是列出,后面会详细解释。
lambda-expression:
lambda-introducer lambda-declaratoropt compound-statement
lambda-introducer:
[ lambda-captureopt ]
lambda-capture:
capture-default
capture-list
capture-default , capture-list
capture-default:
&
=
capture-list:
capture
capture-list , capture
capture:
identifier
& identifier
this
lambda-declarator:
( parameter-declaration-clause ) attribute-specifieropt mutableopt exception-specificationopt trailing-return-typeopt
第四,进一步的分析
上面的标准形式中,最不好理解的可能就是lambda-capture了。其实它对应的就是闭包的概念,而作用是描述外部传入的参数。
wiki上有一个例子,如下
std::vector<int> someList;
int total = 0;
std::for_each(someList.begin(), someList.end(), [&total](int x) {
total += x;
});
std::cout << total;
这段代码做的事情是把someList中的所有变量求和。其中定义的lambda函数如下,
[&total](int x) {total += x;}
与前面的例子不同,这里的lambda-introducer是[&total]而不是之前的[]。这么写的作用是,在这个lambda函数中以引用方式使用外部变量total,这样求和结果就可以存放于这个变量中。那么类似的,还可以以传值方式使用外部变量,写成[total]就可以,而且,如果需要用到的外部变量较多,可以有简略的写法。一个完整的列表如下(来自wiki,这里我把他们翻译成我们比较习惯的表述形式)
[] // 没有定义任何变量。使用未定义变量会导致错误。
[x, &y] // x 以传值方式传入(默认),y 以引用方式传入。
[&] // 任何被使用到的外部变量皆隐式地以引用方式加以使用。
[=] // 任何被使用到的外部变量皆隐式地以传值方式加以使用。
[&, x] // x 显示地以传值方式加以使用。其余变量以引用方式加以使用。
[=, &z] // z 显示地以引用方式加以使用。其余变量以传值方式加以使用。
c++ 将lambda表达式作为参数传递
、获取变量类型
#include <typeinfo.h> int a = ; typeid(a).name(); 、lambda表达式用法
C++ 提供了对匿名函数的支持,称为 Lambda 函数(也叫 Lambda 表达式)。Lambda 表达式把函数看作对象。Lambda 表达式可以像对象一样使用,比如可以将它们赋给变量和作为参数传递,还可以像函数一样对其求值。Lambda 表达式本质上与函数声明非常类似。
[capture](parameters)->return-type{body} //例如
[](int x, int y) -> int { int z = x + y; return z + x; } int main(){
int a = ;
int b = ; auto lambda = []{return a + b;};
//error! 空捕获列表,无法使用作用域内其他变量 auto lambda = [](int a, int b){return a + b;};
//success auto lambda = [=]{return a + b;};
//success, 值传递 auto lambda = [=]{a++; b++; return a + b;};
//error! 值传递无法修改变量值 auto lambda = [&]{a++; b++; return a + b;};
//success, 引用传递 auto lambda = [&a, b]{a++; b++; return a + b;};
//error, 变量a引用传递,变量b值传递,故b不可修改 }
模板参数
#include <iostream>
#include <string> template <typename F>
void print(F const &f){
std::cout<<f()<<std::endl;
} int main() {
std::cout << "Hello, World!" << std::endl; int num = ;
auto a = [&]//以引用的方式捕获本函数中的变量
() //无参数
->std::string {//返回值的类型为std::string
return std::to_string(num);
};
print(a);
num++;
print(a); return ;
}
调用print时,C++编译器会自动推断F的类型。运行上述程序,得到如下输出 Hello, World! 编译器需要支持c++11标准,有的编译器可能需要添加参数-std=c++。 使用std::function
#include <iostream>
#include <functional>
#include <string> void print(std::function<std::string ()> const &f){
std::cout<<f()<<std::endl;
} int main() {
std::cout << "Hello, World!" << std::endl; int num = ;
auto a = [&]//以引用的方式捕获本函数中的变量
() //无参数
->std::string {//返回值的类型为std::string
return std::to_string(num);
};
print(a);
num++;
print(a); return ;
}
stdL::function是个模板类;模板参数:返回值类型+函数参数类型列表;例如std::function<int (int, int)> f,f可以指向任意一个返回指为int,参数为两个int类型的函数。 观察上面的程序,lambda表达式无参数,返回值类型为string;故在print函数中声明一个类型为function<std::string ()>类型的变量f,就可以用来接收a。注意:f前面必须加上const,否则编译过不了。至于加不加&,需要视程序而定,一般加上。
C++11 lambda表达式使用场景解析
Lambda表达式的使用场景
其实我在刚开始使用lambda的时候就挺好奇什么时候使用好,经常在不需要使用的时候使用上了,真的是多此一举,那么要在什么情况下使用呢?
因为lambda表达式又叫匿名函数(当然我们也可以理解为是一个未命名的内联函数),那么肯定就跟函数挂上关系了,通常情况写你在编程的时候需要将这段代码封装到一个函数里面再来调用,那这个时候就避免不了想函数名了,其实有时候取名字真的是件麻烦事,有时脑子突然短路都不知道命什么名字好了,那么这个时候你就要想起我们的lambda表达式了,它可以很好的帮你解决命名困难症这个问题。
那么还有什么情况下可以去考虑使用lambda表达式呢?在你的整个项目编程中,你独立出来一个函数,但这个函数实现相对简单并且可能在整个项目只使用了一次(即不存在复用的情况),那么这个时候我们就可以考虑使用下lambda表达式了,这样可以让代码更加紧凑,更加容易维护。
详解 C++11 lambda表达式的更多相关文章
- C# Lambda表达式详解,及Lambda表达式树的创建
最近由于项目需要,刚刚学完了Action委托和Func<T>委托,发现学完了委托就必须学习lambda表达式,委托和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表达式学习
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 ...
随机推荐
- P1903 [国家集训队]数颜色 / 维护队列(带修莫队)
题目描述: 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. ...
- wordpress实现主动推送+熊掌号推送同步进行
今天给一个朋友http://www.myunigift.cn/ 这个站点是用wordpress,今天帮他改造熊掌号,于是做了数据同步推送. 只要把下面的代码写到funtions.php里面,发布文章的 ...
- LG4723 【模板】常系数线性递推
P4723 [模板]常系数齐次线性递推 题目描述 求一个满足$k$阶齐次线性递推数列${a_i}$的第$n$项. 即:$a_n=\sum\limits_{i=1}^{k}f_i \times a_{n ...
- Django --- 常用字段及参数
1 ORM字段 AutoField int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为id的列. IntegerField 一个整数类型 ...
- 使用笔记:TF辅助工具--tensorflow slim(TF-Slim)
如果抛开Keras,TensorLayer,tfLearn,tensroflow 能否写出简介的代码? 可以!slim这个模块是在16年新推出的,其主要目的是来做所谓的“代码瘦身” 一.简介 slim ...
- xml文件整理
xml 97-2003 格式 \s*\n\s*\n\s*\n\s*\n\n(^个人补充信息.*)\n(.*)\n(^总成绩.*)$1$2\n$3(^个人补充信息.*)\n(.*)\n(.*)\n(^总 ...
- 【爬虫】把抓到数据存起来——爬虫绝配mongodb
[爬虫]把抓到数据存起来——爬虫绝配mongodb 视频地址 抓取数据的方法,前面的课程该讲的都已经讲了,爬取下来数据只是第一步,第二步就是要先存起来.我们最容易想到的就是存文件里喽,python写文 ...
- grep命令选项
-c:只输出匹配行的计数. -I:不区分大 小写(只适用于单字符). -h:查询多文件时不显示文件名. -l:查询多文件时只输出包含匹配字符的文件名. -n:显示匹配行及 行号. -s:不显示不存在或 ...
- ElasticSearch 初识ES
版权声明:本文为博主原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/u013047584/article/det ...
- 【一起来烧脑】一步学会AngularJS系统
AngularJS是一个JavaScript框架 一个用JavaScript编写的库 [外链图片转存失败(img-JUTh171K-1563341248796)(https://upload-imag ...