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表达式替换compSize
displayVector(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 表达式”是一个匿名函数,可以包含表达式和语句 ...
随机推荐
- 解题:JSOI 2007 重要的城市
题面 考虑一个点$x$,如果某两个点$u,v$间的所有最短路都经过$x$,那么$x$肯定是重要的.这个题$n$比较小,所以我们直接跑floyd,在过程中记录 当发生松弛时,我们具体讨论: 如果这个长度 ...
- 【组合数学】【P5216】DLS采花
Description DLS 有 \(N\) 个花田,每个花田里有 \(a_i\) 朵花. DLS 喜欢稀奇古怪的花田,他希望重新排列花田,然后去采花. 但 DLS 采花又有一个癖好:他会从左往右采 ...
- 在eclipse中安装 Activiti Designer插件
转: Activiti系列——如何在eclipse中安装 Activiti Designer插件 这两天在评估jbpm和Activiti,需要安装一个Activiti Designer插件试用一下. ...
- c++操作mysql入门详解
首先,根据你当前的操作系统,还有开发工具,选择相应的mysql版本.本人选择的环境是win10 + vs2013 需要解决三个问题:1.下载安装mysql服务器,并登录mysql测试一下是否安装成功: ...
- linux命令总结kill命令详解
1.作用 kill命令用来中止一个进程. 2.格式 kill [ -s signal | -p ] [ -a ] pid ... kill -l [ signal ] 3.参数 -s:指定发送的信号. ...
- java基础-引用数据类型之一维数组(Array)
java基础-引用数据类型之一维数组(Array) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数组的定义 1>.为什么需要数组 保存一个数据可以定义一个变量,如果要保 ...
- svn 节点处冲突 解决
问题描述: [root@localhost ] $ svn up 正在升级 ‘.’: 已跳过 ‘bg0605’ – 节点处于冲突状态 版本 175. 冲突概要: 跳过的路径:1 解决方法: 当前目录下 ...
- Spring 中出现相同名称的 bean 的处理机制
小总结: 如果启用组件扫描,bean名称不同时,Spring将尝试创建一个bean,即使该类的bean已经在spring-config.xml中定义了. 但是,如果在spring配置文件中定义的bea ...
- js便携小方法,你值得拥有
引言: 本章没有深奥的讲解js一些底层原理,比如this指针.作用域.原型啦,涉及的都是一些有利于平时开发时简化代码,提高执行效率,或者说可以当做一种经验方法来使用,篇幅都不长,小步快跑的让你阅读完整 ...
- 【转】WPF的知识
[-] 闲话WPF之二XAML概述 闲话WPF之五XAML中的类型转换 闲话WPF之十六WPF中的资源 2 闲话WPF之十九WPF中的传递事件 1 闲话WPF之二十WPF中的传递事件 2 闲话WPF之 ...