C++11的auto使用方法
auto在C语言已经失去了意义
我们来谈谈C++11的auto使用方法
我们上代码
示例1:
这里的x和y的类型我们没有确定,但是有了上面a和ft的定义,auto可以推导出x是整型,y是double型。x和y分别会被自动识别成int,double型。
不过这里使用auto去编程的可读性很差,如果没有a和ft的定义,auto还要根据数据去定义类型。
示例2:
auto的另一个作用:可以推导出函数的返回类型。
示例3:
这里的x就是指向函数add的函数指针
示例4:
把构建好的对象给给x
auto使得简化了对类型的定义
这里必须是实体的对象去给给x
decltype的使用
这个关键字decltype的作用是识别出实体(这里的10)的类型,并且可以拿这个类型去定义新的变量。b的类型就是x的类型,x是int类型,所以b也是int 类型。
auto应用在容器(范围广)
auto 从容器的begin()开始到末尾打印,但是不能逆向打印。
auto的弊端
但是auto的弊端在:人在看源码,会越看越糊涂!代码清晰度差,如果你不看函数的声明,不知道返回类型,不知道auto推导出的是什么。
对代码的跟踪和识别能力差
阅读源码的能力变弱
如果你不知道fun的返回值,就会很糊涂!
C++11的lambda
请问没有名字的变量有什么?
我们malloc申请的空间就没有名字。
lambda是没有名字的仿函数。
示例1:
把lambda的表达式给给f1,把b传进去,a=b=20;
我们这里的lambda表达式是在主函数的作用域。
什么叫捕获?不捕获?
理解一下这句代码哪个可以哪个不可以使用?
lambda对全局变量和全局函数没有捕获不捕获之说。因为全局变量全局函数所有人都可以使用。lambda是匿名函数自然也可以使用全局变量全局函数。
示例2:
捕获是对谁来讲的呢?
如果我们的lambda是定义在主函数里,那么它的捕获范围就是主函数的所有局部变量都可以使用。这就是捕获。
[]是不捕获,所以我们不能使用主函数的局部变量。更不可能去使用其他函数的局部变量。因为lambda作用域是在主函数里面。捕获是相当于主函数(作用域)来说。
示例3:
这样lambda可以把主函数的所有局部变量以引用的形式进行捕获。
这里对a,b的改变就是对主函数的a,b改变。
出现这个结果是因为我们还没调动lambda
光定义lambda表达式而没有去执行调用它,就不会改变a,b的值
一般情况下,不要拿&引用捕获,否则局部变量,局部变量在使用用lambda捕获,在其他情况可能会被调用改变了。
示例4:
如果是按值捕获,系统认为你捕获进来的是常性值,不让你对其进行修改!
只可读取,不能修改。
示例5:
书写主函数进行测试:
lambda的聪明之处:如果没有用到,就不会构造。如果你用了,就构造了。调动拷贝构造函数创建同名对象! 但是两个Obj是不一样的,产生了副本!!!
虽然名字一样,但是不是同一个对象。
编译器很聪明,如果你不执行Obj.GetValue();不使用Obj,就不会产生写时拷贝!
如果我们定义了10个对象
调用一个对象,但是产生了10个对象的副本。
捕获整个数组,形式要和数组保持一致,也要产生10个副本。
如果是引用捕获,就不产生副本!
示例6:
不让只捕获数组中的某一个元素。
示例7:
可以挑着捕获,可以分形式捕获。
写上全局的lambda是没有意义的。全局域不需要捕获。
示例8:
不能捕获x,因为x是在a的块的作用域里面。
除非捕获函数也在a的块内
示例9:
mutable是易变关键字。在常方法中可以对mutable修饰的变量进行改变。
打印出什么呢???
虽然调用了lambda,但是没有进行打印副本,改的是副本的值。
示例10:
调动f5和调动f4一模一样
示例11:
不能进行相互赋值
示例12:
可以把lambda表达式赋值给函数指针
但是不能把函数指针赋值给lambda表达式
lambda表达式只能够被构建,不能去赋值
示例13:
可以捕获当前函数作用域的局部变量,a,b,
这里的value来自于对象。
但是它捕获this指针并不是捕获一个指针,而是一个对象,value是对象的value值。
第26行可以对value++的原因是什么?
我们捕获到p,不能对p进行改变,但是可以对p指向的进行改变。
我们捕获的是this指针,this指针不能变,但是this指针所指之物可以改变!
示例14:
具体的写到后面
lambda表达式到底是什么?
lambda表达式和仿函数
解析:
构建对象传参进去for_each函数,对count的++就是对x的++,计数。
对象调动仿函数。
下面这个是以lambda表达式
lambda是仿函数的工作
lambda实现多线程打印
10个线程进来都挂起,执行go函数,唤醒所有线程。
用lambda去实现
如果ready为真,从等待函数返回,如果ready为假,就一直等待。