定制操作_3
隐式捕获
要求编译器根据lambda体中的代码来推断我们要使用那些变量。
这里=表示值捕获,&表示引用捕获
//sz为隐式捕获,值捕获方式
void fun1(vector<string> &words, vector<string>::size_type sz)
{
auto wc=find_if(words.begin(), words.end(), [=](const string &s){return s.size()>=sz;});
}
//这里=表示值捕获,&表示引用捕获
void elimDups(vector<string> &words)
{
//按字典顺序排列
sort(words.begin(), words.end());
//unique重排输入范围,使每个单词出现一次
//排列在范围的前部,返回不重复区域之后一个位置的迭代器
auto end_unique=unique(words.begin(), words.end());
//使用向量操作erase删除重复单词
words.erase(end_unique, words.end());
}
//如果ctr的值大于1,返回word的复数形式
string make_plural(size_t ctr, const string &word, const string &ending)
{
return (ctr>1)?word+ending:word;
}
void binggies(vector<string> &words, vector<string>::size_type sz, ostream &os=cout, char c=' ')
{
elimDups(words); //将words按字典顺序排列,删除重复单词
//按长度排序,长度相同的单词维持字典序
stable_sort(words.begin(), words.end(),
[](const string &a, const string &b){return a.size()<b.size();});
//获取一个迭代器,指向第一个满足size()>=sz的元素
auto wc=find_if(words.begin(), words.end(),
[sz](const string &a){return a.size()>=sz;});
//计算满足size>=sz的元素的数目
auto count=words.end()-wc;
cout<<count<<" "<<make_plural(count, "word", "s")
<<" of length "<<sz<<" or longer "<<endl;
//打印长度大于等于给定值的单词,每个单词后面接一个空格
//os隐式捕获,引用捕获方式;C显示捕获,值捕获方式
for_each(words.begin(), words.end(), [&, c](const string &s){os<<s<<c;});
//os显式捕获,引用捕获方式;C隐式捕获,值捕获方式
for_each(words.begin(), words.end(), [=, &os](const string &s){os<<s<<c;});
}
这里记住了哦,当我们使用混合使用隐式捕获和显示捕获的时候,捕获列表中的第一个元素必须是一个&或=。
还有还有!!!!!
那就是混合使用的时候,显示使用了&或=,则隐式捕获只能使用显示没有使用的另外一个,是=或&
可变lambda
哈哈,以上全部都是没办法改变lambda参数列表的值的!!!
这里告诉大家怎么去改变参数列表的值哦!!
有两种方式,一种运用关键字,一种用引用。
//改变参数列表的值mutable
void fun2()
{
size_t v1=42; //局部变量
//f可以改变他所捕获的变量的值
auto f=[v1]() mutable {return ++v1;};
v1=0;
auto j=f(); //j是43
}
//引用改变值的大小依赖于是否是const类型
void fun3()
{
size_t v1=42; //局部变量
//v1是一个非const变量的引用
//可以通过f2中的引用来改变它
auto f2=[&v1]{return ++v1;};
v1=0;
auto j=f2(); //j为1
}
指定lambda返回类型
这里记住lambda的语句体里面只能包含一个return语句,默认情况下,如果一个lambda体包含return之外的任何语句,则编译器假定此lambda返回void。
void你也懂那是空,也就是不能返回值了- -#。真蛋疼!!
<pre name="code" class="cpp">
void Demo10_21(){ int a=21; bool j=true; //捕获它,然后判断是否是0,不是就-- auto d10_21=[&a]{return (a==0)? true:--a;}; while(!j) { j=d10_21(); } cout<<" a的值变为 "<<j;}
这个有个问题啊!!!那就是我的到的结果居然是!!!!!-------是 1 啊,为毛不是0。
改进版!!!
void Demo10_21()
{
int a=21;
int b=a;
//捕获它,然后判断是否是0,不是就--
auto d10_21=[&a]{return (a==0)? false:--a;};
while(b>0)
{
auto j=d10_21();
cout<<" a的值变为 "<<j<<endl;
--b;
}
}
好吧!我承认上面那个其实是做错了,因为j是true的所以一次循环都没有- -#;
参数绑定
标准库bind函数
这个可以看成是一个通用的函数适配器,
适配器!!!(了解什么是适配器)
调用bind的一般形式就是:
auto newCallable = bind(callable, arg_list);
我发现C++primer里面特别爱用auto,尼玛这样了还要数据类型有何用??
绑定check_size的sz参数
//check6是一个可调用对象,接受一个string类型的参数
//并用此string和值6来调用check_size
void fun4()
{
auto check6=bind(check_size, _1, 6);
}
使用placeholders名字
名字_n都定义在placeholders的命名空间里面
/**
* 功能:定制操作lambda
* 时间:2014年6月20日07:43:15
* 作者:cutter_point
*/
#include<iostream>
#include<numeric>
#include<algorithm>
#include<string>
#include<vector>
#include<functional>
using namespace std;
//sz为隐式捕获,值捕获方式
void fun1(vector<string> &words, vector<string>::size_type sz)
{
auto wc=find_if(words.begin(), words.end(), [=](const string &s){return s.size()>=sz;});
}
//这里=表示值捕获,&表示引用捕获
void elimDups(vector<string> &words)
{
//按字典顺序排列
sort(words.begin(), words.end());
//unique重排输入范围,使每个单词出现一次
//排列在范围的前部,返回不重复区域之后一个位置的迭代器
auto end_unique=unique(words.begin(), words.end());
//使用向量操作erase删除重复单词
words.erase(end_unique, words.end());
}
//如果ctr的值大于1,返回word的复数形式
string make_plural(size_t ctr, const string &word, const string &ending)
{
return (ctr>1)?word+ending:word;
}
void binggies(vector<string> &words, vector<string>::size_type sz, ostream &os=cout, char c=' ')
{
elimDups(words); //将words按字典顺序排列,删除重复单词
//按长度排序,长度相同的单词维持字典序
stable_sort(words.begin(), words.end(),
[](const string &a, const string &b){return a.size()<b.size();});
//获取一个迭代器,指向第一个满足size()>=sz的元素
auto wc=find_if(words.begin(), words.end(),
[sz](const string &a){return a.size()>=sz;});
//计算满足size>=sz的元素的数目
auto count=words.end()-wc;
cout<<count<<" "<<make_plural(count, "word", "s")
<<" of length "<<sz<<" or longer "<<endl;
//打印长度大于等于给定值的单词,每个单词后面接一个空格
//os隐式捕获,引用捕获方式;C显示捕获,值捕获方式
for_each(words.begin(), words.end(), [&, c](const string &s){os<<s<<c;});
//os显式捕获,引用捕获方式;C隐式捕获,值捕获方式
for_each(words.begin(), words.end(), [=, &os](const string &s){os<<s<<c;});
}
//改变参数列表的值mutable
void fun2()
{
size_t v1=42; //局部变量
//f可以改变他所捕获的变量的值
auto f=[v1]() mutable {return ++v1;};
v1=0;
auto j=f(); //j是43
}
//引用改变值的大小依赖于是否是const类型
void fun3()
{
size_t v1=42; //局部变量
//v1是一个非const变量的引用
//可以通过f2中的引用来改变它
auto f2=[&v1]{return ++v1;};
v1=0;
auto j=f2(); //j为1
}
void Demo10_21()
{
int a=21;
int b=a;
//捕获它,然后判断是否是0,不是就--
auto d10_21=[&a]{return (a==0)? false:--a;};
while(b>0)
{
auto j=d10_21();
cout<<" a的值变为 "<<j<<endl;
--b;
}
}
//check6是一个可调用对象,接受一个string类型的参数
//并用此string和值6来调用check_size
int main()
{
Demo10_21();
return 0;
}
PS:上课了,我得逃了,拜拜,亲爱的各位,待我明日归来!!!
本文深入探讨了C++中lambda表达式的高级应用,包括隐式捕获、可变lambda、参数绑定及绑定技巧。通过具体实例展示了如何在不同场景下灵活使用lambda,以及需要注意的关键细节。

被折叠的 条评论
为什么被折叠?



