lambda表达式与bind函数
#include<iostream>#include<algorithm>#include<sstream>#include<vector>#include<cstring>#include<functional>//bind函数的头文件//#include <boost/tokenizer.hpp>usingnamespace std;usingnamespace placeholders;//_n占位符所要使用的命名空间/*** 本程序首先将一个字符串划分成单词存储到容器中去* 在使用系统提供的算法时,讨论了一元谓词与二元谓词* 接下来讨论了lambda表达式及其用法** 在很多地方使用同一个函数,一个操作需要很多语句才能完成* 通常采用使用函数而不是lambda表达式,为了解决一元谓词等的限制,引入标准库bind函数*/void elimDups(vector<string>& words){sort(words.begin(), words.end());auto end_unique = unique(words.begin(), words.end());words.erase(end_unique, words.end());}bool compElement(const string & str){return str.length()<5?1:0;}void displayVector(vector<string>::iterator beginPos,vector<string>::iterator endPos){while(beginPos != endPos){cout <<*(beginPos++)<< endl;}cout << endl;}/**< 值捕获 */void fcn1(){size_t v1 =42;//将v1拷贝到名为f的可调用对象auto f =[v1]{return v1;};//从lambda类类型生成一个类对象f。在f创建时,使用捕获变量V1给其数据成员v1进行初始化(值拷贝),v1 =0;v1 = f();cout <<"显式捕获--值赋值--"<< v1 << endl;}/**< 默认情况下,值捕获是不能改变变量的值,若要改变则需加上mutable关键字 */void fcn4(){size_t v4 =42;auto f4 =[v4]()mutable{return++v4;//观察与fcn1的区别};cout <<"mutable--"<< f4()<< endl;cout <<"mutable--v--"<< v4 << endl;//非引用捕获无法更改捕获变量的值}/**< 引用捕获 */void fcn2(){size_t v1 =42;auto f2 =[&v1]//在f2被创建时,其成员变量v1将引用外部的v1{v1 =100;//v1是非const类型,故而能被修改return v1;};//构建一个lambda类对象,使用v1给对象的数据成员赋值,此时函数体并未执行cout << v1 << endl;//42---函数体未执行cout << f2()<< endl;//100---函数体开始执行cout <<"显式捕获--引用赋值--"<< v1 << endl;//42---采用的是引用捕获,在函数体被执行时,v1被修改}/**< 隐式捕获 */void fcn3(){int v3 =0;auto f3 =[=]{return v3;};cout <<"隐式捕获--值赋值--"<< f3()<< endl;auto f4 =[&]{v3 =100;return v3;};cout <<"隐式捕获--引用赋值--"<< f4()<< endl;cout << v3 << endl;}/*** 混合捕获方式(前边的符号代表隐式捕获的类型,后边的参数列表要与其不同)* [&,identifier_list] identifier_list采用值捕获方式,identifier_list列表中的各个名字前不能使用&* 而任何隐式捕获的变量都采用引用方式捕获* [=,identifier_list] identifier_list采用引用捕获方式,identifier_list列表中的各个名字之前必须使用&* 而任何隐式捕获的变量都采用引用方式捕获*//**< bind函数的实现 *///先实现要绑定的函数,然后在要使用的地方使用bind函数进行绑定bool newCompElement(const string & str,constint sz){return str.length()< sz ?1:0;}int main(){char wordLine[]="The consequences of today are determined by the actions of the past. \To change your future, alter your decisions today.";vector<string> strVector;/**istringstream lineStream(wordLine);//istringsream默认以空格或\t或\n切割字符串,不能进行设定while(lineStream>>word){strVector.push_back(word);}*///strtok()char seps[]=" ,.\t\n";char* word = strtok(wordLine, seps);while(word != NULL){strVector.push_back(word);word = strtok(NULL, seps);}for(auto val : strVector){cout << val <<" ";}cout << endl;// elimDups(strVector);/**< 根据字符串长度是否 < 5,将容器中的字符串重新排列 */vector<string>::iterator partPos = partition(strVector.begin(), strVector.end(), compElement);displayVector(partPos, strVector.end());/*** 尾置返回类型* auto func(int i) -> int(*)[10];* 这是一个函数声明,该函数返回一个指针,该指针指向含有10个int类型的数组** lambda表达式:* [capture list] (parameter list) -> return type {function body}* 通常定义一个可调用f,使其等于该lambda表达式* 例如:auto f = [] {return 42;};** lambda的调用方式与普通函数的调用方式相同,都是使用调用运算符* cout << f() << endl;//打印42* lambda表达式可以忽略参数列表和返回类型,但必须包含捕获列表和函数体(内容可以为空)* 捕获列表只用于局部非static变量,lambda可以直接使用局部static变量和在其函数之外声明的名字*/size_t sz =5;auto compSize =[sz](const string & str)->bool{return str.length()< sz;};partPos = partition(strVector.begin(), strVector.end(), compSize);//这里也可以直接使用lambda表达式替换compSizedisplayVector(partPos, strVector.end());/**< 使用bind函数进行绑定 */auto newCompEle = bind(newCompElement, _1, sz);partPos = partition(strVector.begin(),strVector.end(), newCompEle);//相当于partition(strVector.begin(),strVector.end(), bind(newCompElement, _1, sz));displayVector(partPos, strVector.end());/**< 测试lambda的各种捕获 */fcn1();fcn2();fcn3();fcn4();return0;}/*** 默认情况下,bind那些不占位符在给bind对象进行赋值时采用的是值拷贝的方式* 如要要用引用方式传递或绑定对象无法进行拷贝,使用ref来实现引用方式传递** bind(words.begin(),words.end(),bind(print,ref(os),_1,' ');* ostream &print(ostream &os,const string &s,char c);** 函数ref返回一个对象,包含给定的引用,此对象是可以拷贝的。* cref函数保存const引用的类*/
lambda表达式与bind函数的更多相关文章
- C++ Primer : 第十章 : 泛型算法 之 lambda表达式和bind函数
一.lambda表达式 lambda表达式原型: [capture list] (parameter list) -> retrue type { function body } 一个lambd ...
- kotlin之lambda表达式和匿名函数
lambda表达式,称为匿名函数,是一种函数字面值,也就是没有声明的函数,但可以作为表达式传递出去. 函数类型: 对于接受另一个函数的作为自己的参数,必须针对这个参数指定一个函数的类型如 fun &l ...
- Python函数与lambda 表达式(匿名函数)
Python函数 一.函数的作用 函数是组织好的,可重复使用的,用来实现单一或相关联功能的代码段 函数能提高应用的模块性和代码的重复利用率 python 内置函数:https://docs.pytho ...
- Lambda表达式公共拼接函数(原创)
#region Lambda公共拼接函数 /// <summary> /// LambdaWhere(枚举) /// </summary> public enum Lambda ...
- 第三天 函数 三元运算 lambda表达式 内置函数 文件操作
面向过程: 直接一行一行写代码,遇到重复的内容复制黏贴. 不利于代码阅读 代码没有复用 面向对象 将代码块定义为函数,以后直接调用函数 增强了复用性 函数的定义方法 def 函数名(传递参数): 函数 ...
- lambda表达式,map函数
lambda只是一个表达式,不需要定义函数,故也是匿名函数,用法为:lambda 参数:表达式. x=5 list1=[2,3,4] list2=[10,20,30] s=lambda x:x**3 ...
- C++11 Lambda表达式(匿名函数)
http://www.cnblogs.com/RainyBear/p/5733399.html http://blog.163.com/lvan100@yeah/blog/static/6811721 ...
- lambda表达式、匿名函数
lambda表达式是函数式编程中的匿名函数语法规范. In computer programming, an anonymous function (function literal, lambda ...
- Lambda 表达式-即匿名函数
拉姆达值(Lambda),希腊字母表示为Λ,指与真空的空间有关的能量或暗能量. 代表转换的常量.或者转换本身. Lambda 表达式 Lambda 表达式”是一个匿名函数,可以包含表达式和语句 ...
随机推荐
- BZOJ 3438 小M的作物 & BZOJ 1877 [SDOI2009]晨跑
我由衷地为我的朋友高兴.哈哈,yian,当你nick name破百上千时,再打“蒟蒻”就会被打的. 好的,说正事吧.请注意,这还是题解.但我发现,网络流实在是太套路了(怪不得这两年几乎销声匿迹).我们 ...
- 使用VS2012调试Dump文件
前一节我讲了怎么设置C++崩溃时生成Dump文件 , 点击 传送门 , 这一节我讲讲怎么使用 VS2012 调试生成的 Dump 文件 , 甚至可以精确到出错的那一行代码上面 ; 1. 生成 Dump ...
- [poj 1533]最长上升子序列nlogn树状数组
题目链接:http://poj.org/problem?id=2533 其实这个题的数据范围n^2都可以过,只是为了练习一下nlogn的写法. 最长上升子序列的nlogn写法有两种,一种是变形的dp, ...
- insert sort
插入排序将数据分为前面有序部分和后面无序部分,取无序部分的第一个元素插入到有序序列中. 注意与选择排序的区别. // insert sortvoid insertionSort(int arr[], ...
- P1558 色板游戏
P1558 色板游戏 题目背景 阿宝上学了,今天老师拿来了一块很长的涂色板. 题目描述 色板长度为L,L是一个正整数,所以我们可以均匀地将它划分成L块1厘米长的小方格.并从左到右标记为1, 2, .. ...
- Java DataSource
ojdbc的jar包 在使用连接oracle数据库的时候尽量使用服务端E:\app\80953\product\11.2.0\dbhome_1\jdbc\lib下的jar包,否则可能会出错! 在JDK ...
- clock()、time()、clock_gettime()和gettimeofday()函数的用法和区别
1. clock_gettime( ) 提供了纳秒的精确度 int clock_gettime(clockid_t clk_id, struct timespect *tp); clockid_t c ...
- HTTP协议(1)-------- 网络编程
1. HTTP简介 HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传送协议.它可以使浏览器更加高效,使网络传输减少. ...
- jvm内存模型(运行时数据区)
运行时数据区(runtime data area) jvm定义了几个运行时数据区,这些运行时数据区存储的数据,供开发者的应用或者jvm本身使用.按线程共享与否可以分为线程间共享和线程间独立. 线程间独 ...
- java 根据二叉树前序 ,中序求后续
在一棵二叉树总,前序遍历结果为:ABDGCEFH,中序遍历结果为:DGBAECHF,求后序遍历结果. 我们知道: 前序遍历方式为:根节点->左子树->右子树 中序遍历方式为:左子树-> ...