【足迹C++primer】32、定制操作_3

定制操作_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:上课了,我得逃了,拜拜,亲爱的各位,待我明日归来!!!大笑








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值