C++ lambda 表达式
来源:互联网 发布:箪食壶浆以迎将军乎 编辑:程序博客网 时间:2024/06/07 12:55
1. 我们可以传递任何种callable object给算法,一个object或者expression 称为callable 是因为我们可以应用call operator。
我们说e是一个callable expression,那么我们可以写这样的代码:
<span style="font-size:18px;"><span style="white-space:pre"></span>e(arg);</span>
arg是用逗号隔开的argument list。
2. callable:function,function pointer,重载了function call operator的class,以及lambda 表达式。
3. lambda表达式可以被认为是一种unnamed inline function。
4. lambda表达式的形式为:
<span style="font-size:18px;"><span style="white-space:pre"></span>[capture list](parameter list)->return type{function body}</span>
5. lambda没有default argument,因此call a lambda 总是传递和parameter数量相同的argument。
6. lambda能够使用local variables只有当它specified它将要使用的variables才行。lambda通过将这些variables包括在他的capture list来specified这些variables。
7. 当我们定义一个lambda,编译器生成一个新的未命名的class type corresponds to that lambda。当我们传递一个lambda给一个function的时候,我们同时define一个new type以及一个这个type的object。
8. 当我们capture by value的时候,要确保variables能够被copy。同时,value of a capture variable 被copied当lambda被创造的时候,而不是被called的时候。
9. 当我们capture by reference的时候,要确保referenced的object当lambda执行的时候还存在。
10. 当我们implicit capture variables的时候,我们使用[&],[=]来告诉编译器我们到底是capture by reference还是capture by value。同时,当我们同时使用implicit capture 和explicit capture的时候,我们必须使capture list 的第一个是&或者=,同时explicit capture要和implicit capture的类型相反。
11. by default,lambda不会改变那些capture by value 的variable 的值,当我们想要改变的时候,我们这样:
<span style="font-size:18px;"><span style="white-space:pre"></span>auto f=[v]mutable{return v++;}</span>
12. Bydefault,如果一个lambda的function body 包括除了return之外的其他语句,lambda都被认为return void。
如:
<span style="font-size:18px;"><span style="white-space:pre"></span>transform(vi.begin(),vi.end(),vi.begin(),[](int i){if(i<0) return –I; else return I;}</span>
这导致error,因为lambda return a void type 但是我们返回了一个值。
当我们想要定义一个返回值的时候,我们可以这样做:
<span style="font-size:18px;"><span style="white-space:pre"></span>transform(vi.begin(),vi.end(),vi.begin(),[](int i)->int { if(i<0) return –I; else return I;}</span>
13. 我们可以很容易将capture list 为空的lambda改为一个函数传递给算法,但是对于那些capture local variables 的lambda,则没有这么简单,因为算法通常用 unary predicate或者binary predicate。
14. 解决上面的问题,当我们需要将local variable传递到函数中,又希望可以将此函数传递给算法,我们可以使用bind function,如下:
<span style="font-size:18px;"><span style="white-space:pre"></span>for_each(word.begin(),word.end(), bind(print,ref(os),_1,’‘);</span>
在这里,newCallable就是一个callable object,arg_list是逗号隔开的argument list,correspond to parameter of callable。
在arg_list里会有一些_n的项,这些argument是placeholder,代表了newCallable中的parameter,_1代表newCallable的第一个parameter,_2代表第二个。
代码例子:
<span style="font-size:18px;"><span style="white-space:pre"></span>auto wc=find_if(word.begin(),word.end(), bind(check_size,_1,sz));</span>
注:bind定义在functional头文件里。
15. _n定义在名叫placeholder的namespace里,placeholder又定义在std的namespace里,
<span style="font-size:18px;"><span style="white-space:pre"></span>using::std::placeholder::_1;</span>
我们也可以这样简化
<span style="font-size:18px;"> <span style="white-space:pre"></span>using namespace std::placeholder</span>
16. bind函数可以帮助我们对参数重排序。
<span style="font-size:18px;"><span style="white-space:pre"></span>sort(word.begin(),word.end(),bind(isShorter,_2,_1);</span>
改变了参数顺序后,实际上使得排序方向正好相反。
17. 有时候,我们需要bind函数去binding reference parameter,通常那些不是placeholder的argument都是被copy到bind函数return的callable object里的。如果要binding reference parameter,可以这样做。
<span style="font-size:18px;"><span style="white-space:pre"></span>for_each(word.begin(),word.end(), bind(print,ref(os),_1,’‘);</span>
ref()函数返回一个包括了给定的reference的object,而且这个object是copyable的。我们还可以用cref()函数生成一个包括了reference to const的类。
- 【c/c++】Lambda表达式
- C#--Lambda表达式
- C#:Lambda 表达式
- C++lambda表达式
- C++lambda表达式
- C# Lambda表达式
- C++:lambda表达式
- C#Lambda表达式
- 【c++】lambda表达式
- C++lambda表达式简记
- c#lambda表达式复习
- [C++]Lambda表达式简介
- 【C#】理解Lambda表达式
- 【C++】Lambda表达式
- C++lambda表达式
- C++Lambda表达式用法
- C++:lambda表达式
- 【C#】Lambda表达式
- POJ 1003 Hangover
- Pull解析器解析XML文件
- mysql体系结构
- 文章标题
- 统计大串中小串出现的次数
- C++ lambda 表达式
- 学习strcpy函数中的问题
- 非常好的理解遗传算法的例子
- 17个学术论文搜索引擎
- [poj3735 Training little cat]【矩阵快速幂】
- 【C语言】猴子吃桃问题
- 第六周项目六 复数模板类(3)
- HTTP请求的基本过程
- SOAP Webservice用AFNetworking实现请求