首页 > 编程语言 >5月15日c++小语法右值引用,lambda表达式,和多线程

5月15日c++小语法右值引用,lambda表达式,和多线程

时间:2023-05-15 22:23:02浏览次数:38  
标签:15 函数 右值 可以 线程 引用 多线程 lambda

c++中有一个东西叫做左值引用和右值引用,因为面向对象语言中有很多封装好的自定义类型容器,而这些容器又不像内置类型那样传值方便,有时候可能会有很大的深拷贝浪费于是有了左值引用:在函数传参时方便的传引用避免了传复杂的指针,而在返回之上直接传引用减少了不必要的深拷贝.而右值引用又在这基础上解决了传进来的引用如果是将亡值则直接进行转移拷贝.又进一步的减少了一次深拷贝.而在传返回值时若传回来的是一个临时变量的将亡值则转移拷贝又可以减少资源的浪费.例如若一个函数中生成了一个临时变量并需要将这个临时变量传出去,此时就不可以用传左值引用,若是使用传值则需要拷贝构造一个临时变量,然后将这个临时变量再考呗构造给外面用,此时调用了两次这个变量的构造函数,而用右值引用接收这个具有常性的临时变量,在转移拷贝此时就只是调用了一次构造函数就完成了传值.

右值引用的场景:

1:重载一些自定义类的拷贝构造与赋值运算符,使其判断传入将亡值的情况进行转移构造.

2:就是上面说的情况处理一些比较消耗大的传值返回.

3:重载一些自定义容器的插入函数,这个与第一种情况比较类似,也是判断将亡值的情况,一般的容器中的emplace和push接口都有重载这个右值引用.只不过emplace的优点在于在接口上传入匿名构造的元素他可以自己构造.比如vector<pair<K,V>>的容器若是push插入就需要用make_pair构造一个匿名pair传入或者初始化一个pair对象传入,而emplace不仅用上面的方法调用也可以直接传入K,V自己构造pair进行插入.

所以总而言之右值引用就是传进来的变量出去了也是释放,不如让我继续利用.

需要注意的是模版参数的右值引用既可以接受左值又可以接收右值,然后右值引用在经历过二次以后传参后就会发生右值属性的丢失,所以需要用到完美转发.格式为Forward(T)T为目标右值.

 

 

 可以看到没有用到完美转发的都变成了左值.

一个小点:move函数可以让左值变得可以被右值引用.可以理解为加上了右值属性.

lambda表达式:有以下场景:

 stl里面的sort函数可以根据仿函数模版参数传入不同的仿函数从而达到控制升序和降序的结果,这个函数可以去用库里面有的也可以自己去写.:

但是如果是需要按自定义类型的不同属性去排上面的仿函数肯定是不行的,所以得用到模版的特化:

 但是这样又太繁琐了要根据不同的情况写好多种函数,这是lambda表达式就可以派上用场了.

他的格式为[函数作用域外的捕捉列表](传入的参数列表)->返回值类型{函数体}然后这个整体可以赋给一个auto自己推出来类型的对象,所以他可以像仿函数和函数指针那样用,就是说可以传给仿函数参数.因为他的底层本质就是一个重载()运算符的函数.只不过函数名是lambda<+系统分配的uuid.

 上图中在sort函数中的仿函数模版参数位置传入了一个lambda表达式,[]中不需要向外部捕获变量所以为空而函数参数列表需要传入两个good结构体返回值类型是bool类型,函数实现部分是{}里面的.这样想要换排序的key就可以随时换很方便.[]可以捕获外面的变量,它分为一个传值捕获,和传引用.传值捕获的东西不可以改变,如果非要改变就加mutable关键字修饰然后再改但是没有什么用,要改变可以直接传引用改变.如果一次要捕获很多数据就直接用[=]或[&]全局捕获.

总而言之lambda用法和函数很像.他有实例化对象,也可以直接传表达式整体.

多线程:

一个程序中main函数就可以说是一个主线程,而在以前的学习中几乎都是一个程序跑一个线程,涉及到计算机组成原理的一些知识(还没学)反正多线程某些情况下跑的比单线程要快所以这里说一下多线程.

 

 上面的代码,就是两个线程(加上main三个)对x自增计算,可以看到线程t1自增1000000次线程t2自增1000000所以理论结果应该是2000000次但是运行结果却不是这样

 可以看到只自增了一百一十多万次,因为++x这句话分三部分组成,第一步是拿到这个x.第二部对这个x加一第三部放回这个x,两个线程都会有这三部,而这三步在每一步是都有可能被另一个线程影响,所以需要在++x这句话不能不影响,有下面两种常用的方法:

1:对一段代码上锁:时++x在执行时不受影响;如第一个图:

2:使用库里面的原子编程使++x成为一个指令,也可以避免冲突的情况.如图二

 

 还有就是并不是上锁的代码越断越好,因为太短了线程会来回切的很频繁而导致变慢.

如果一个很庞大的数据量需要多线程来执行.如果像上面那样一次一个thread未免太慢了.,以你为thread是一个类型名,所以可以将它装入容器中,然后不断匿名实例化线程装入容器,让它自己跑.就像下图中所示,想vector中装入了n个线程,让他们自己跑.

 可以看到mian函数中有一个join函数,因为main函数完了程序就完了,但是main函数里弄出来的线程还没有跑完,所以可以当作mian函数执行join方法时是在等t1线程执行结束.

 以上代码的意思是用两个线程分别输出100以内的奇数和偶数,运行结果如下图:

 可以看到两个线程挤压了屏幕输出导致输出错乱此时就需要想一个办法如何防止两个线程冲突输出,可以运用上锁和解锁来解决,在每次进行第一个for循环代码时对第二个线程上锁,第一个线程每次for循环完了后上给第二个解锁,然后第二个开始时对第一个上锁,结束后解锁,这样有序进行就可以解决了.

 这样就解决了

标签:15,函数,右值,可以,线程,引用,多线程,lambda
From: https://www.cnblogs.com/qjwxlj/p/17403327.html

相关文章

  • 每日总结 5.15
    今天上课进行了进一步的代码2书写。主要是进行广告方面的设计对于数据库的管理。try{pre=c.prepareStatement(sql);pre.setString(1,"111");//pre.setString(2,tel);res=pre.executeQuery();......
  • 每日总结2023-05-15
    今天对项目中广告做出了处理:1.新建数据库表,为id,广告播放者、广告名、链接、是否启用。2.将对对应的影视文件上传到云服务器中,通过外网访问链接。3.将原先本地视频url改为对应的云端视频文件。对于本人的Android项目,正在进行手机唯一标识登录学习。......
  • 建民打卡日记5.15
    一、问题描述一个整数“犯二的程度”定义为该数字中包含2的个数与其位数的比值。如果这个数是负数,则程度增加0.5倍;如果还是个偶数,则再增加1倍。例如数字-13142223336是个11位数,其中有3个2,并且是负数,也是偶数,则它的犯二程度计算为:3/11×1.5×2×100%,约为81.82%。本题就请你计算一......
  • 5月15日
    习题:题目:定义一个Dog类,包括体重和年龄两个数据成员及其成员函数,声明一个实例dog1,体重5,年龄10,使用I/O流把dog1的状态写入磁盘文件。再声明一个实例dog2,通过读取文件dog1的状态赋给dog2。分别用文本方式和二进制方式操作文件。设计思路:设计一个类包含体重和年龄两个成员,包括构造......
  • 23-5-15--c++文件基本操作--dog
    定义一个Dog类,包括体重和年龄两个数据成员及其成员函数,声明一个实例dog1,体重5,年龄10,使用I/O流把dog1的状态写入磁盘文件。再声明一个实例dog2,通过读取文件dog1的状态赋给dog2。分别用文本方式和二进制方式操作文件。#include<iostream>#include<fstream>#include<string>usin......
  • 5.15打卡
    一、问题描述:2000以内的不小于4的正偶数都能够分解为两个素数之和(即验证歌德巴赫猜想对2000以内的正偶数成立)。二、设计思路:该问题我们可以采用函数来解决。定义一个函数,函数名设为fun,在其中判断传进来的实际参数(设为n(n=2)),是否为素数,如果是素数则返回1,否则返回0。在判断是......
  • 5.15每日总结
    今天上课老师讲了人机交互设计,讲了软件的设计如何变得更加人性化,满足用户的真实需求。还在团队中讨论了后续的项目冲刺验收要完成的任务和分工,未来要实现和改进哪些功能。之后的时间对记账本App页面的交互设计进行了一些改进。......
  • 5.15 2.8
    一、问题魔术师利用一副牌中的13张黑桃,预先将它们排好后迭在一起,并使牌面朝下。然后他对观众说:我不看牌,只要数数就可以猜到每张牌是什么,我大声数数,你们听,不信?你们就看,魔术师将最上面的那张牌数为1,把它翻过来正好是黑桃A,他将黑桃A放在桌子上,然后按顺序从上到下数手中的余牌......
  • 5.15
    #include<stdio.h>voidmain(){longmul,number,k,a,b;printf("Itexistsfollowingautomorphicnmberssmallthan100000:\n");for(number=0;number<100000;number++){for(mul=number,k=1;(mul/=10)>0;k*=10);a=k*10;mul=0;b=10;while(k>0){mul=......
  • 算法基础上机实验——2023.5.15
    1.#include<cmath>#include<cstdio>#include<iostream>#include<algorithm>usingnamespacestd;intmain(){inta[310],n,k=0;cin>>n;while(n!=-99999){a[k++]=n;cin>>......