当前位置: 首页 > news >正文

接网站建设外包的工作总结延安商城网站开发设计

接网站建设外包的工作总结,延安商城网站开发设计,wordpress如何添加注册登录,南京小程序制作开发一直想写一篇文章,来总结lambda表达式,但是之前感觉总结的不是特别到位,现在看了几篇文章和视频后,感觉对lambda表达式有了比较深刻的认识,现在进行记录总结如下: lambda表达式又叫做匿名函数,…

一直想写一篇文章,来总结lambda表达式,但是之前感觉总结的不是特别到位,现在看了几篇文章和视频后,感觉对lambda表达式有了比较深刻的认识,现在进行记录总结如下:

lambda表达式又叫做匿名函数,lambda表达式本质是一个匿名类,lambda为了我们能更方便的定义出一个函数方法提供了便利,下面咱们开始介绍下lambda表达式。

1.lambda表达式的引出

首先我们想完成一个   Add的函数,这个函数有个功能,就是把自己成员变量的值num_,和传进来的参数x相加,并且返回。我们一般用C++的写法如下:

#include<typeinfo>
#include<iostream>
#include<functional>
using namespace std;
class Cal{
public:
Cal(int num):num_(num){cout<<"num_ :"<<num_<<endl;
};
int Add(int x){ cout<<"x+num_:"<<x+num_<<endl;return x+num_;
};
private:const int num_;
};int main(){Cal temp(5);temp.Add(3);return 0;
}

编译并且执行程序:

zhc@ubuntu:~/test/linux$ g++ -std=c++14  test.cpp -o test && ./test 
num_ :5
x+num_:8

接下来我们用仿函数来实现,仿函数也就是重载小括号  ()的类,我们修改代码如下:

#include<memory>
#include<typeinfo>
#include<iostream>
#include<functional>
using namespace std;
class Cal{
public:
Cal(int num):num_(num){cout<<"num_ :"<<num_<<endl;
};
int operator () (int x){ cout<<"x+num_:"<<x+num_<<endl;return x+num_;
}
private:const int num_;
};
int main(){Cal Add(5);Add(3);return 0;
}

编译并且输出结果:

zhc@ubuntu:~/test/linux$ g++ -std=c++14  test.cpp -o test && ./test 
num_ :5
x+num_:8

也就是说如果我们想实现一个简单的Add函数,也要定义一个类,或者用成员函数实现,或者用仿函数实现,有没有一种写法上更简单的方式呢,省略掉类的定义,那么我们的主角就要登场了,就是lambda表达式.看如下代码:

#include<memory>
#include<typeinfo>
#include<iostream>
#include<functional>
using namespace std;
int main(){int num=5;auto lam_add=[num](int x) ->int {cout<<"num+x:"<<num+x<<endl;return num+x;};  lam_add(3);return 0;
}

是不是形式上简洁了许多,输出结果如下:

zhc@ubuntu:~/test/linux$ g++ -std=c++14  test.cpp -o test && ./test 
num+x:8

正如我们的lambda表达式结果看,这个跟我们刚才写的仿函数类也是基本相同的,实际上我写的第二个例子,就是这个lambda表达式在调用的时候,生成的临时类对象,所对应的类的定义,

注意我的成员变量的写法,const int num_,这个是我故意这么写的,因为确实等价方式就是这样。下面我们来讲一讲lambda表达式的捕获列表,以及不同捕获形式,在生成类的成员函数里的可读可写属性。

2. lambda表达式的捕获列表

lambda表达式的书写形式如下:

[captrue] (params) opt -> ret {body};
其中,capture是捕获列表;params是参数列表;
opt是函数选项(mutable,noexcept等关键字);
ret是返回值类型;body是函数体。

lambda表达式可以通过捕获列表捕获一定范围内的变量:

[]不捕获任何变量;

[bar]按值捕获bar变量,同时不捕获其他变量,并作为副本在函数体使用(按值捕获);

[&bar]按引用捕获bar变量,同时不捕获其他变量;并作为引用在函数体使用(按引用捕获);

[=]捕获外部作用域作用变量,并作为副本在函数体使用(按值捕获);

[&]捕获外部作用域所有变量,并作为引用在函数体使用(按引用捕获);

[=,&foo]按值捕获外部作用域所有变量,并按引用捕获foo变量;

[this]捕获当前类中的this指针,让lambda拥有和当前类成员函数同样的访问权限,如果已经使用了&或者=,就默认添加此选项。捕获this的目的是可以在lambda中使用当前类的成员函数和成员变量。

一般,不会捕获全局变量,静态全局变量,局部静态局部变量,静态成员变量。

下面我们按照按值捕获和按引用捕获来说明下,捕获后在生成的匿名类里的成员变量情况,与外部变量的可写属性是否相同,以及是否能够改变外部变量。

下面咱们看下具体的例子:

#include<memory>
#include<typeinfo>
#include<iostream>
#include<functional>
using namespace std;
int main(void){
int m=1;
const int n=2;
auto g = [m,n](int x)->int{
m++;
n++;
return m+n;};
int z=g(0);
return 0;
}

编译代码并且执行:编译报错如下:

zhc@ubuntu:~/test/linux$ g++ -std=c++14  test.cpp -o test && ./test 
test.cpp: In lambda function:
test.cpp:10:2: error: increment of read-only variable ‘m’m++;^~
test.cpp:11:2: error: increment of read-only variable ‘n’n++;^~

具体结论相关的东西见下面的两个图,说的更清楚一些。

 这个图是我从别的地方copy过来的,暂时粘贴这里,后期再敲试验代码。

如果我们想改变这个   m,p的可写属性,可以在    lambda表达式中加入mutalbel关键字。

我画红线的部分,是原文书写错误,应该是有mutable时。

 这里强调一点,这个  const int n,在用这个mutable以后,那么对应的成员变量还是  const int n ,也就是说这个属性,是拿 mutable改变不了的。

3.lambda表达式中的  准函数,准对象,如何接收lambda表达式

当一个lambda表达式没有捕获任何外部变量时,则可以看成一个准函数,如果捕获了外部对象,则可以看成一个准对象。具体见下面图片。

 那么对于这种准对象的情况,我们是怎么接呢,c++  11中推出了std::function   模板类,它即能接准函数的情况,也能接准对象的情况。下面我们来简单的介绍下std::function.

std::function的实例可以对任何可以调用的目标实体进行存储、复制、和调用操作,这些目标实体包括普通函数、Lambda表达式、函数指针、以及其它函数对象等。std::function对象是对C++中现有的可调用实体的一种类型安全的包裹(我们知道像函数指针这类可调用实体,是类型不安全的)。

std::function包含于头文件 #include<functional> 中,可将各种可调用实体进行封装统一,包括

  • 普通函数
  • lambda表达式
  • 函数指针
  • 仿函数(functor 重载括号运算符实现)
  • 类成员函数
  • 静态成员函数

其中具体的使用方式,这里其他的就不再举例子,因为在我的另外一个文章中有介绍。这里就说一个lambda表达式的例子:

#include<memory>
#include<iostream>
#include<functional>
#include<map>
#include<string>
using namespace std;class SaveStuInfo{
public:void SaveInfo(const string& num,std::function<string(const string&,const string&)> callback){student_info.insert(make_pair(num,callback));
}void CallLmd(const string &num){string name = "zhc";string score = "100";student_info[num](name,score);
}
private:using get_name_score = std::function<string(const string &,const string &)>;std::map<std::string, get_name_score> student_info; //num as key};int main(void){
string num="123";
//string name ="zhc";
//string score="100";
auto lmd = [](const string&name,const string&score) ->string{cout<<"lmd was called value: "<<name+score<<endl;return name+score;
};
SaveStuInfo  temp;
temp.SaveInfo(num,lmd);
temp.CallLmd(num);
return 0;
}

这里要注意一点,在temp.SaveInfo(num,lmd),这个时候不要写成,temp.SaveInfo(num,lmd(name,score));这样会报错,换句话说,std::function,里不用存储具体的lambda参数里的值,真正传递的lambda参数是在调用这个lambda表达式的时候。

编译并且执行程序结果如下:

zhc@ubuntu:~/test/linux$ g++ -std=c++14  test.cpp -o test && ./test 
lmd was called value: zhc100

http://www.yayakq.cn/news/430471/

相关文章:

  • 网站扁平化布局做网站的安全证书
  • 建站快车品牌石柱网站制作
  • 黄页网站推广公司企业网址怎么制作
  • 河北省建设信息中心网站网站建设 锐颖科技
  • 做网站外包哪家好北京有哪些炫酷的网站页面
  • 中医网站模板网站按照谁建设 谁负责
  • 织梦网站模板源码昆明网站建设优化企业
  • 成都零起飞网站建设本厂有大量手工活外发
  • 广东网站建设哪家好展会广告策划公司
  • 成都免费建网站公司网页升级重要通知请拿好笔记本
  • 2019广东省工程建设网站怎么开通微信小程序卖东西
  • 河南省汝州市文明建设网站查失信被执行人名单查询
  • 绵阳网站建设设计做直播网站找哪个网站
  • 苏州网站公司性价比高柳州网站建设
  • 微信公众号 网站开发h5营销型网站
  • 池州做网站的公司公司网站建设一般要多少钱
  • 2018网站建设涉及网站左边logo图标怎么做
  • 试用型网站怎么用自己笔记本建设网站
  • 织梦手机网站制作兰州网站制作服务电话
  • 学校门户网站建设工作室内设计师怎么找
  • .net 网站管理系统福州品牌网站建设公司
  • 开发建设网站手机网站抢拍是怎么做的
  • 利用高权重网站做关键词朝阳区北京网站建设
  • 紫云网站建设即速应用微信小程序官网
  • 网站建设案例展示不可上网
  • 网站设计项目建设内容网络规划的研究内容
  • 网站登陆系统怎么做淘宝宝贝关键词排名查询工具
  • 做网站不会P图怎么办上海人才网档案查询
  • 公司网站设计与管理杭州网络
  • 做请帖的网站做自己的网站有什么用