-
Notifications
You must be signed in to change notification settings - Fork 3
/
03.ass
644 lines (642 loc) · 93.7 KB
/
03.ass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
[Script Info]
Title: 从汇编角度看编译器优化
ScriptType: v4.00+
PlayResX: 1920
PlayResY: 1080
Original Script: woclass
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Default,微软雅黑,80,&H00FFFFFF,&H0000FFFF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2.0,1,2,10,10,10,1
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Dialogue: 0,0:00:01.48,0:00:09.23,Default,,0,0,0,,今天我们来给大家介绍的是现代 C++ 中的500元编程
Dialogue: 0,0:00:09.23,0:00:11.49,Default,,0,0,0,,首先什么是五百?
Dialogue: 0,0:00:11.49,0:00:13.10,Default,,0,0,0,,那很为什么?
Dialogue: 0,0:00:13.10,0:00:24.09,Default,,0,0,0,,就是首先这是我们这节课的大纲,这是第三节课第一节课的录播,可以在这里看到
Dialogue: 0,0:00:24.09,0:00:28.93,Default,,0,0,0,,然后我们就是首先什么是模板呢?
Dialogue: 0,0:00:28.93,0:00:31.84,Default,,0,0,0,,要搞清楚什么是模板
Dialogue: 0,0:00:31.84,0:00:54.12,Default,,0,0,0,,首先要明白为什么要模板,就是之前就如果就是用传统面向对象的思想,就是如果我要实现一个串子函数,它的功能是将一个数乘以2 ,然后就是它需要定义三个重载
Dialogue: 0,0:00:54.12,0:01:07.52,Default,,0,0,0,,首先是对in 重载,对flow 的存在,对double 也要充分,这样才能在调用的时候有自动会去调用不同的重载函数
Dialogue: 0,0:01:07.52,0:01:20.82,Default,,0,0,0,,但这样有一个问题,就是如果我哪天突然需要long 的乘以二这个函数,那它就得再重新写一遍就浪费时间
Dialogue: 0,0:01:20.82,0:01:34.73,Default,,0,0,0,,所以说我们需要用模板使用了模板之后呢,可以看到这个区别就是它首先可以发现啊,这是it 这是it 这是flow 这是float
Dialogue: 0,0:01:34.73,0:01:41.25,Default,,0,0,0,,那我就总结一下规律,就说这里如果是T的话,那这里也是
Dialogue: 0,0:01:41.89,0:01:57.86,Default,,0,0,0,,然后在上面写template class t 就代表这个T是一个占位符,它可以被替换为it float 或者double ,就是它会自动去生成一个对应的函数,明白吧?
Dialogue: 0,0:01:57.86,0:02:12.13,Default,,0,0,0,,就是我们这里用class t 就代表T是一个类型,有的教材会写temporary temporary name 7 ,它也是代表类型,它们两个是完全一样的
Dialogue: 0,0:02:12.13,0:02:15.70,Default,,0,0,0,,我喜欢用class 有问题吗?
Dialogue: 0,0:02:16.54,0:02:20.73,Default,,0,0,0,,很卡吗很卡吗?
Dialogue: 0,0:02:23.47,0:02:24.75,Default,,0,0,0,,有还卡吗?
Dialogue: 0,0:02:24.75,0:02:44.58,Default,,0,0,0,,现在就是我们可以就是用间括号代表调用一个模板的实例,用如果间括号印成的,它调用就是把替换成了印传,和这个一样,可能也把然后更进一步
Dialogue: 0,0:02:44.58,0:03:07.55,Default,,0,0,0,,模板函数还有一个方面问题,就是它能够自动推到这个T就你不需要去指定了,它自动看到右边是个二十一嘛啊21 这里T出现在模板参数里,所以它就会直接认为啊你这个调用者是in it ,对吧?
Dialogue: 0,0:03:07.55,0:03:11.48,Default,,0,0,0,,那它就会自动等价于串式括号int
Dialogue: 0,0:03:12.12,0:03:15.88,Default,,0,0,0,,所以说这个就是它能够自动推导
Dialogue: 0,0:03:15.88,0:03:22.61,Default,,0,0,0,,就如果你这个参数类型就直接是个T的话,它会自动退档的
Dialogue: 0,0:03:23.97,0:03:26.41,Default,,0,0,0,,电脑端会卡吗?
Dialogue: 0,0:03:29.79,0:03:34.99,Default,,0,0,0,,可能是你的wifi 网络比较慢吧
Dialogue: 0,0:03:36.21,0:03:45.25,Default,,0,0,0,,总之这样的话它用起来就和模板函数一样方便啊,不是重载一样方便了
Dialogue: 0,0:03:45.25,0:03:55.47,Default,,0,0,0,,然后然后还有一个就是它就是有的时候我们遇到一个问题,就是我想要把T乘以2
Dialogue: 0,0:03:55.47,0:04:09.17,Default,,0,0,0,,但是我们想要有一个特例,就是比如对于实际类型,也就是字符串 C++ 的这个实际类型,它是没有乘以2
Dialogue: 0,0:04:09.17,0:04:14.07,Default,,0,0,0,,这个函数呢它只能用T加T来代替乘2
Dialogue: 0,0:04:14.07,0:04:22.14,Default,,0,0,0,,所以说我们就希望就对于这这这些基本的类型我都统一用乘以2
Dialogue: 0,0:04:22.14,0:04:32.81,Default,,0,0,0,,但仅仅对实际上这个特例我是用T加T这时候就可以用我们的重载和模板混编的形式
Dialogue: 0,0:04:32.81,0:04:42.90,Default,,0,0,0,,这种就是它会变成一个比如这里调用时间系调用的话,它就会变成这个钻石的特例
Dialogue: 0,0:04:43.23,0:04:46.69,Default,,0,0,0,,他就不会再去用通用的模板
Dialogue: 0,0:04:49.15,0:04:51.88,Default,,0,0,0,,原话不行是吗?
Dialogue: 0,0:04:52.21,0:04:58.71,Default,,0,0,0,,那应该是你网速问题嗯,有问题吗?
Dialogue: 0,0:04:59.46,0:05:31.38,Default,,0,0,0,,就是比如这个,然后之后就是如果这个策划有一个问题,就是它不会自动把一个constant 恰成给转换成使劲,它反而是会把cos 的恰成认为是T就是这样去调用的话,它会去调用这个,然后就变成了cos 的恰乘乘以这个2 ,从而就出错了
Dialogue: 0,0:05:31.38,0:05:56.06,Default,,0,0,0,,当然也有一种办法就是SFINAE你可以搜一下,就是在这后面加一个enable f 如果T不是cos 恰成的话,我才去调用,这个没问题吧,那就是你网速的问题呀,对吧?
Dialogue: 0,0:05:57.83,0:06:17.72,Default,,0,0,0,,然后然后这个模板参数就是之前不是说T如果出现在参数列表里,那他是它是能够自动根据你的参数类型推断题的
Dialogue: 0,0:06:17.72,0:06:34.59,Default,,0,0,0,,但这次我们弄了一个Q它的功能是返回一个指定类型的R但是这时候它没有参数了,就直接这样去调用它是不知道其实什么的必须手动指定
Dialogue: 0,0:06:34.59,0:06:41.34,Default,,0,0,0,,但也可以就是说我们在定义模板所在这里写class 7等于inter
Dialogue: 0,0:06:41.34,0:06:56.02,Default,,0,0,0,,也就是如果我这个监控号making ,它会默认变成in 这个和函数的默认参数是一样的,只不过它是一件括号的形式,是更有问题吗?
Dialogue: 0,0:06:57.78,0:07:20.60,Default,,0,0,0,,那我继续吧,然后就是除了可以用class t 代表T作为一个类型作为模板的参数外,还可以用template internet 就代表把N作为间括号与参数,而N是一个整数类型
Dialogue: 0,0:07:20.60,0:07:30.00,Default,,0,0,0,,比如我们这里实现了修碳物质,就是代表的这个这个后面的参数重复N次
Dialogue: 0,0:07:30.00,0:07:42.70,Default,,0,0,0,,就比如说他们是1万 ,就代表把one 打印一次,它会自动把一带入到这里,三带入到这里,四带入到这里
Dialogue: 0,0:07:42.70,0:07:56.89,Default,,0,0,0,,不过这样长一个int 参数,它有一个缺点,就是它只支持整数和媒体类型,它不能传float 类型,也不能传用户自定义的
Dialogue: 0,0:07:56.89,0:08:07.68,Default,,0,0,0,,就比如GOMV,可像这种是不行的,你必须传三个inter 进去才可以,怎么办呢?
Dialogue: 0,0:08:09.85,0:08:18.23,Default,,0,0,0,,对呀,点K呀有问题吗?
Dialogue: 0,0:08:18.23,0:08:29.14,Default,,0,0,0,,然后你就会想,为什么我要把intern 作为一个模板参数,我直接作为这个括号与参数不相吗?
Dialogue: 0,0:08:29.47,0:08:38.29,Default,,0,0,0,,其实是有区别的,区别,待会儿再说,然后就是多模板参数的默认值
Dialogue: 0,0:08:38.29,0:09:01.51,Default,,0,0,0,,它有一个特点,就是它不一定是要最后几个位等于多少就可以为第一个就是N等于一,然后之后没有也可以的,它和函数参数的默认值不一样,它这个因为它是可以自动从这个括号里面推断出了嘛
Dialogue: 0,0:09:01.51,0:09:09.93,Default,,0,0,0,,所以这个时候我们只给一个,他这个是自动推断的,不需要classic in 的,不需要
Dialogue: 0,0:09:10.95,0:09:20.99,Default,,0,0,0,,然后这时候就嗯什么都没有的话呢,N就取默认只有一个的话呢,它能够自动推断
Dialogue: 0,0:09:21.86,0:09:34.58,Default,,0,0,0,,然后就是刚才提到了是这个修探路的T这个T是直接作为参数
Dialogue: 0,0:09:34.94,0:09:52.70,Default,,0,0,0,,然后还有一种就是它这个漆是一个另一个模板类的那个参数啊,这样的话它也能够自动匹配,它是一种部分特化的效果,就它这个仍然是模板的
Dialogue: 0,0:09:52.70,0:10:05.71,Default,,0,0,0,,但它不是完全,比如这个应该是这个漆,它就代表任何一个七组成的victor 都能调用我上这个函数
Dialogue: 0,0:10:06.04,0:10:19.10,Default,,0,0,0,,然后当然也要记得我们上一节课所说的,如果是比较昂贵拷贝的类型,最好用cos 的和来避免拷贝哦
Dialogue: 0,0:10:19.10,0:10:24.02,Default,,0,0,0,,然后上午的功能就是艾瑞的每个数加起来
Dialogue: 0,0:10:24.02,0:10:29.49,Default,,0,0,0,,比如瑞兹从零加到艾瑞的,在每个商家,然后返回
Dialogue: 0,0:10:29.49,0:10:38.51,Default,,0,0,0,,可以看到这里就是4加3加2加1 的值,然后这是3.1乘以2.78等于10
Dialogue: 0,0:10:38.51,0:10:47.53,Default,,0,0,0,,但是这样也有一个问题,就是如果你直接把这个括号写在这的话,他可能就不行
Dialogue: 0,0:10:50.69,0:11:00.62,Default,,0,0,0,,然后然后就是刚才我提到的问题,为什么不把这个intent 作为这个参数呢?
Dialogue: 0,0:11:00.62,0:11:18.35,Default,,0,0,0,,一定要弄个监控号,他们是有区别的,就是这两个有区别就是template 产物的N啊,它是编译器的常量,不是每一个N它都会单独的生成一个函数
Dialogue: 0,0:11:18.35,0:11:30.64,Default,,0,0,0,,也就是说就比如刚才这个N如果我N为零的话,那这个编译器就会自动把这个for 循环给优化掉
Dialogue: 0,0:11:31.39,0:11:43.68,Default,,0,0,0,,再比如N等于一的话,它就编译器就知道N是一样,还不用把整个波循环删掉,只剩一个含这个循环体
Dialogue: 0,0:11:44.02,0:11:49.22,Default,,0,0,0,,然后为三呢,他可能就把这个语句重复三遍
Dialogue: 0,0:11:49.22,0:12:08.87,Default,,0,0,0,,然后为四呢,他可能觉得太多了,他就不重复了,就是说他可以自动去allow 这个这个潭这个循环起allow 就是展开的意思就是让N为一个常数,编译器就不知道怎么优化了
Dialogue: 0,0:12:08.87,0:12:23.61,Default,,0,0,0,,而如果作为N乘以P的话,这个N它就是一个运行时的常数,那编译器就不知道你N是多少,只能从外面调用者才能知道
Dialogue: 0,0:12:23.61,0:12:32.37,Default,,0,0,0,,然后他就没办法做刚才说的这个这个自动啊如何优化了,明白吗?
Dialogue: 0,0:12:32.37,0:12:33.71,Default,,0,0,0,,有人吗?
Dialogue: 0,0:12:34.44,0:12:38.16,Default,,0,0,0,,你们都在圣诞节现场吗?
Dialogue: 0,0:12:38.16,0:12:42.55,Default,,0,0,0,,没人是线充吗?
Dialogue: 0,0:12:46.44,0:12:48.32,Default,,0,0,0,,我在录吗?
Dialogue: 0,0:12:48.32,0:13:02.37,Default,,0,0,0,,我录了,然后就是呃通常来说就是模板,它虽然有可以让编译器优化的好处,但它也有几个坏处
Dialogue: 0,0:13:02.37,0:13:19.37,Default,,0,0,0,,就是他会编译很多很多次用你的恩美编一次他就编译器就会重新实例化一遍这个修泮函数,也就是说变异时间会延慢
Dialogue: 0,0:13:19.70,0:13:29.39,Default,,0,0,0,,然后还有一个问题就是编译器必须看得到suitable 的定义,它才能使你画它呀
Dialogue: 0,0:13:29.39,0:13:51.79,Default,,0,0,0,,就比如如果我的message 是一个我自定义的类型,那这个see out 又用message ,那他这个我怎么知道他有没有这个这个成员包含了,所以就是导致模板函数必须定义在同一个文件里才能用
Dialogue: 0,0:13:51.79,0:14:01.49,Default,,0,0,0,,也就是必须为那个内联的,或者说在头文件里的就是没办法分离声明和定义
Dialogue: 0,0:14:01.83,0:14:18.37,Default,,0,0,0,,所以说不是很编译慢的原因,很大程度就是因为他用了很多很多的模板,头文件,非常非常的大,给我变得很慢啊,有外星吗?
Dialogue: 0,0:14:19.02,0:14:21.25,Default,,0,0,0,,无无线充吗?
Dialogue: 0,0:14:21.25,0:14:35.00,Default,,0,0,0,,不会不会模板函数,就是我跟你说一个有趣的现象,就是如果你这样写的话,这个其实和直接这样写是一样的
Dialogue: 0,0:14:35.43,0:14:42.67,Default,,0,0,0,,就是如果你想让他那一年你还是得给他加上stay tank 或者in line
Dialogue: 0,0:14:42.67,0:14:48.17,Default,,0,0,0,,就是如果你不加status tank ,它是会导出这个符号
Dialogue: 0,0:14:48.17,0:14:59.48,Default,,0,0,0,,不过这个符号是一个符号,也就是说如果两个文件都定义了这个函数的话,那它会取其中一个
Dialogue: 0,0:14:59.48,0:15:07.88,Default,,0,0,0,,所以必须保证两个函数中呃,两个实现中这个函数必须必须是一致的
Dialogue: 0,0:15:07.88,0:15:19.79,Default,,0,0,0,,就如果你写两个不同的那个实践的话,如果你写了两个不同的实现
Dialogue: 0,0:15:19.79,0:15:21.61,Default,,0,0,0,,好,我给你看看啊
Dialogue: 0,0:15:25.27,0:15:33.59,Default,,0,0,0,,他是会选取其中一段如何判断他选了哪一段呢?
Dialogue: 0,0:15:34.26,0:15:46.01,Default,,0,0,0,,我也不知道他到底选了哪个,呃,总之他就是会选取其中那个离他比较近的一个
Dialogue: 0,0:15:46.01,0:15:55.81,Default,,0,0,0,,但是实际上就是你用NM去看一下它生成的符号,它是生成了很多个符号
Dialogue: 0,0:15:55.81,0:16:09.80,Default,,0,0,0,,总之总之就是你想要想要用模板,然后让他那里的话,你还是要加一下statement 了,不能去掉时间放在
Dialogue: 0,0:16:09.80,0:16:21.86,Default,,0,0,0,,对呀,我待会儿就要说了啊,需要我改,所以说模板它通常来说不建议分离声明和实现
Dialogue: 0,0:16:21.86,0:16:28.61,Default,,0,0,0,,如果你一定要分离的话,他要一定要分
Dialogue: 0,0:16:28.61,0:16:42.77,Default,,0,0,0,,先讲这种吧,就是先讲模板应用,就是刚才不是说模板的参数可以作为编译器常量嘛,编译器常量它就能够自动优化
Dialogue: 0,0:16:44.33,0:16:54.20,Default,,0,0,0,,就是说比如我这里有一个sum two 的案例,然后这个编写这个代码的人呢,他自作聪明
Dialogue: 0,0:16:54.20,0:16:59.13,Default,,0,0,0,,他说我加一个flag ,说要不要启用调试模式
Dialogue: 0,0:16:59.13,0:17:06.68,Default,,0,0,0,,如果处于调试模式的话,他就会打印出每个这个从一到N的值
Dialogue: 0,0:17:06.68,0:17:11.04,Default,,0,0,0,,他认为哎呀,这样你就方便我调试了
Dialogue: 0,0:17:11.04,0:17:20.62,Default,,0,0,0,,然后他不考虑,就是他觉得啊那我关闭调试模式,那应该对我的性能没有影响吧
Dialogue: 0,0:17:20.62,0:17:33.98,Default,,0,0,0,,他想的美就是如果我这调试模式即使是关了他,其实CPU执行到这里,他也会去不停的去判断点bug 是不是真
Dialogue: 0,0:17:33.98,0:17:38.33,Default,,0,0,0,,如果是假的话呢,它才能跳过这一串
Dialogue: 0,0:17:38.33,0:17:50.20,Default,,0,0,0,,但虽然现现代编译器和CPU它都能够去优化和判断这个分支,但毕竟这个还是有点影响的
Dialogue: 0,0:17:50.20,0:17:59.98,Default,,0,0,0,,就比如本来这个变异器是可以就把这个N直接优化成一个5050之类的
Dialogue: 0,0:17:59.98,0:18:25.01,Default,,0,0,0,,我们下一讲会讲,就是所以就如果需要让他真正的是那个无开销的插入这么一段代码,就是我们C语言可能是把它作为一个红用FDEFDEBUG那才打印,这样的确是没有开箱
Dialogue: 0,0:18:25.01,0:18:32.92,Default,,0,0,0,,但他的问题就是我商务处只能要么为处,要么为debug,要么不debug
Dialogue: 0,0:18:32.92,0:18:40.51,Default,,0,0,0,,如果需要有debug 又没有debug 的话,可以把debug 作为一个模板参数
Dialogue: 0,0:18:41.08,0:18:57.17,Default,,0,0,0,,这样的话呢你如果去调用项目处有一件括号财务给班主任的话,这个编译器在点bug 的时候,他会说,哎,你这不就是F括号零吗?
Dialogue: 0,0:18:57.17,0:19:05.18,Default,,0,0,0,,那这个语句永远得不到执行啊,编译器就会自动把它给优化掉了啊
Dialogue: 0,0:19:05.51,0:19:17.45,Default,,0,0,0,,然后然后就是如果为Q的话,他就会看到F处,也就是说这个语句是永远会得到执行的呀
Dialogue: 0,0:19:17.45,0:19:25.62,Default,,0,0,0,,那他就会把这个F给去掉了,就直接每次都打印,这样能让结果是一样的
Dialogue: 0,0:19:25.62,0:19:31.06,Default,,0,0,0,,但它本来是生成一个函数,它就生成两个函数了
Dialogue: 0,0:19:31.06,0:19:38.29,Default,,0,0,0,,这两个函数分别对应于有桥式的和没桥式的,明白吧?
Dialogue: 0,0:19:44.76,0:19:57.13,Default,,0,0,0,,然后这个还有一个问题,就是他这个的依赖里面是不是足够智能能够识别到这个点bug 为真
Dialogue: 0,0:19:57.13,0:20:10.92,Default,,0,0,0,,还是就比如如果我这里see out ,就是如果这个点bug 不视为编译器常量,那编译器也没法优化
Dialogue: 0,0:20:10.92,0:20:33.37,Default,,0,0,0,,所以我们可以用f constant x 2 ,就是保证这个括号是一个变异期求值的,也就是它和FF的效果是差不多了,已经不过它是我们 C++ 风格的,而不需要去处理那个红的问题
Dialogue: 0,0:20:36.22,0:20:37.93,Default,,0,0,0,,听得到吗?
Dialogue: 0,0:20:38.78,0:20:49.02,Default,,0,0,0,,然后就是但是account x 它造成的问题就是它里面只能全四边以及常量组成的表达式
Dialogue: 0,0:20:49.02,0:20:56.63,Default,,0,0,0,,如果你把这个作为一个参数传进去的话,那它编译器就会报错
Dialogue: 0,0:20:56.63,0:21:06.88,Default,,0,0,0,,就比如这样,如果I百分比2 ,就是如果它是偶数的话,呃,奇数的话才打赢,那就不行了
Dialogue: 0,0:21:06.88,0:21:22.99,Default,,0,0,0,,因为constant 是判,意思就是你这里必须是变异性常量呀,而你这个S运行时必须在真正的那个值呀,它就会报错,然后这个不能用作常量
Dialogue: 0,0:21:27.69,0:21:39.86,Default,,0,0,0,,然后所以说要还有一个限制,就是他商务处这个调试就是你必须得这样作为一个常量产品
Dialogue: 0,0:21:39.86,0:21:50.22,Default,,0,0,0,,它你想先弄一个呃,叫什么不迭半个的变量,然后再取some two 点半,这样就不行了
Dialogue: 0,0:21:50.22,0:21:54.45,Default,,0,0,0,,因为点bug ,它是里边运行时的变量
Dialogue: 0,0:21:54.45,0:21:59.88,Default,,0,0,0,,虽然你这个变量是初始化为常数了,但他不知道
Dialogue: 0,0:21:59.88,0:22:05.57,Default,,0,0,0,,所以如果你要让兵一起知道,这不知道这是个常数
Dialogue: 0,0:22:05.57,0:22:11.15,Default,,0,0,0,,有一些concept 这样的bug 就可以在编译器求值
Dialogue: 0,0:22:11.15,0:22:20.46,Default,,0,0,0,,但这样的话它的那个等号右边必须有值,而且这个值也不能为边运行时的值
Dialogue: 0,0:22:20.46,0:22:31.45,Default,,0,0,0,,比如C语言的探母函数,他需要知道当前时间这个就不是编译器能搞定的事嘛,对吧?
Dialogue: 0,0:22:32.00,0:22:47.72,Default,,0,0,0,,对呀,证明了两份函数,inter 也会啊也会生成两份函数,会会会会的会的
Dialogue: 0,0:22:50.46,0:22:56.03,Default,,0,0,0,,如果模板参数是inter ,那他就对inter 生成一个服务
Dialogue: 0,0:22:56.03,0:23:01.03,Default,,0,0,0,,如果为那个float ,它就再生成一个float 的实例
Dialogue: 0,0:23:01.03,0:23:06.61,Default,,0,0,0,,如果你输入了一个错误的类型,那它才会出错
Dialogue: 0,0:23:08.19,0:23:20.88,Default,,0,0,0,,然后然后就是刚才说count expert 不就代表一个是编译器常数变量,然后还可以算编译器常数函数
Dialogue: 0,0:23:20.88,0:23:27.95,Default,,0,0,0,,就如果我叠半个小调用一个函数的话,我们还是有这个需要的
Dialogue: 0,0:23:27.95,0:23:35.01,Default,,0,0,0,,比如max 用ABS正确,也是需要用在监控号里的话,它就注册了
Dialogue: 0,0:23:35.01,0:23:42.90,Default,,0,0,0,,所以说我们可以把那个team 作为conflict support ,让它返回就是编译器常量
Dialogue: 0,0:23:42.90,0:23:51.33,Default,,0,0,0,,当然这样的话它在非编译器常用语境下,它也可以调用它的螺丝加个线子
Dialogue: 0,0:23:51.66,0:24:16.18,Default,,0,0,0,,当然就是编译器常量的函数,它这里面也必须是一个能够常量求值,就是constant sport ,不能将用不constant 的函数,而且constant expert 它有一个好处,就是它等于是那年的,而且就是它有一个坏处,就是不能分离胜利和定义
Dialogue: 0,0:24:16.18,0:24:24.01,Default,,0,0,0,,因为这样定义就看不到它内部实现,从而无法保证它是编译器求值的
Dialogue: 0,0:24:24.01,0:24:34.00,Default,,0,0,0,,然后告诉你一个事实,就是标准库的一些函数,比如me 和max 啊,这些也是编译器可以调频的
Dialogue: 0,0:24:34.86,0:24:38.66,Default,,0,0,0,,所以你在监控号里可以使用命和max
Dialogue: 0,0:24:39.29,0:24:54.91,Default,,0,0,0,,你爸爸,然后就是刚才这个同学说的问题,就是如何用了模板还能分离CTP和点
Dialogue: 0,0:24:55.77,0:25:04.14,Default,,0,0,0,,就是如果我们试着用传统的思维,就直接在这里放一个模板的声明
Dialogue: 0,0:25:04.14,0:25:11.46,Default,,0,0,0,,模板的定义它就会出错,它说找不到项目处,为什么呢?
Dialogue: 0,0:25:11.46,0:25:26.55,Default,,0,0,0,,这是因为模板它有一个惰性的特点,就是如果我只是定义了这个template blue blue debug 的话,它是不会把debug 的所有情况都变
Dialogue: 0,0:25:27.54,0:25:34.64,Default,,0,0,0,,你必须手动声明说啊,这个Q是要用的,这个boss 我也要用的
Dialogue: 0,0:25:34.64,0:25:40.98,Default,,0,0,0,,这样你在命里面才会指引到这里
Dialogue: 0,0:25:40.98,0:25:47.79,Default,,0,0,0,,11万嗯,明白了吗?
Dialogue: 0,0:25:48.75,0:25:56.58,Default,,0,0,0,,就是用这个语句,用这个语法来实例化一个模板函数,这样才能分离
Dialogue: 0,0:25:56.58,0:26:06.37,Default,,0,0,0,,但是这样一个问题就是比如你这个不不是不,而是int ,那你这里覆盖了为一,这里为零
Dialogue: 0,0:26:06.37,0:26:16.71,Default,,0,0,0,,那而你调用者说3575括号二这个二没有被实力化,它也看不到实现,那就又会出错了
Dialogue: 0,0:26:16.71,0:26:34.60,Default,,0,0,0,,所以说你这里template 的实例化,必须把每一种情况都写上,否则还是会突破又炸了,有吗有吗?
Dialogue: 0,0:26:34.60,0:26:47.44,Default,,0,0,0,,没有吧,别乱讲,你看正常的没错嘛,现在好了吗?
Dialogue: 0,0:26:48.21,0:26:54.59,Default,,0,0,0,,那不就好了,刚刚应该没在吧
Dialogue: 0,0:26:55.70,0:27:01.74,Default,,0,0,0,,不管,总之就是不建议你分离模板的声明和定义
Dialogue: 0,0:27:01.74,0:27:07.79,Default,,0,0,0,,虽然可以这样,因为它违背了面向对象的开闭原则
Dialogue: 0,0:27:07.79,0:27:14.70,Default,,0,0,0,,也就是如果我新增了一个一个类型的话,我还是另画一遍
Dialogue: 0,0:27:14.70,0:27:29.55,Default,,0,0,0,,那就那就比如就拿STDvictor 举例子吧,如果标准库的制作人员他实力化了,it 实力化了float ,但他忘记实力化CHAR了
Dialogue: 0,0:27:29.55,0:27:40.49,Default,,0,0,0,,然后我突然想到要用CHAR,或者我突然想到要用我自己的一个类作为这个监控号的参数
Dialogue: 0,0:27:40.49,0:27:48.56,Default,,0,0,0,,那编译器就编译,所以说不能尽量不要把模板分离深入和定义吧
Dialogue: 0,0:27:50.21,0:27:55.91,Default,,0,0,0,,最近没接电源,我生怕电源接了他就炸了
Dialogue: 0,0:27:56.96,0:28:26.19,Default,,0,0,0,,现在可以吧,我真怕就是电源造成这个声音,然后模板就是哪怕你这个模板没有任何用,就只是就只是弄了一个假的模板,它也是允许惰性的,就是编译器它不会去看你里面的内容,对不对?
Dialogue: 0,0:28:26.19,0:28:34.70,Default,,0,0,0,,就比如这里我干脆写字符串等于2333 ,这根本不可能通过编译法
Dialogue: 0,0:28:34.70,0:28:50.14,Default,,0,0,0,,然而这却通过编译,就是因为我上面写了一个假模板片,编译器说这个是惰性的,然后编译器说哎没人调用这个函数嘛,那我就不实际化它
Dialogue: 0,0:28:50.14,0:28:53.54,Default,,0,0,0,,所以说这就是延迟编译的技术
Dialogue: 0,0:28:53.54,0:29:18.86,Default,,0,0,0,,如果一个函数你定义在头文件里,而且这个函数有可能是用不到的,那就可以在下面写一个template class 等于voice 这个假模板,让编译器不要去,你记得去编译解析这里面的内容,从而就可以让编译可能会更快
Dialogue: 0,0:29:18.86,0:29:21.63,Default,,0,0,0,,然后它也用于代理模式
Dialogue: 0,0:29:21.63,0:29:45.40,Default,,0,0,0,,就比如我要代理对象没有这个没有这个,比如叫捡塞子的那个那个成员函数,那他也不会出错,只有你调用他的时候,他才会出错,就嗯欠明白吧
Dialogue: 0,0:29:46.85,0:29:58.54,Default,,0,0,0,,然后就是我刚刚赶突然赶出来的一个力,就有的同学说,哎呀,老师先教教你怎么打印一个victory 啊
Dialogue: 0,0:29:58.54,0:30:16.00,Default,,0,0,0,,为什么我直接CL的出错了呀,然后我就编写了一个这个函数,它首先是一个圆括大括号,然后中间把每一个数都打印出来,然后用那个大括号结尾
Dialogue: 0,0:30:16.00,0:30:27.57,Default,,0,0,0,,但是它是一个模板函数,也就是不管你vehicle 是啥类型,它都能够去调用print
Dialogue: 0,0:30:27.57,0:30:41.05,Default,,0,0,0,,print , 也就是in 或者double 它都能调用,它就会在A括号X这里返回的是什么类型,它会自动去调用c out 的不同重载
Dialogue: 0,0:30:41.05,0:30:49.26,Default,,0,0,0,,也就是说我的print 是一个重载的模板函数,而see out 又是一个重载的函数
Dialogue: 0,0:30:49.98,0:31:00.42,Default,,0,0,0,,我们两个互帮互助实现了,只需要我写一遍抽象的代码,就可以应用到所有类型上的效果了
Dialogue: 0,0:31:01.07,0:31:02.95,Default,,0,0,0,,是不是很方便?
Dialogue: 0,0:31:07.85,0:31:17.12,Default,,0,0,0,,然后下一步就是如何用c out 左左A这样去调用呢?
Dialogue: 0,0:31:18.04,0:31:29.03,Default,,0,0,0,,就是这样我们可以用运算符重载operate 左左,然后返回也是一个o steam ,这样就可以连锁调用
Dialogue: 0,0:31:29.03,0:31:36.75,Default,,0,0,0,,然后左边是个OSDM,OSDM就是STDCout 的那个类型
Dialogue: 0,0:31:36.75,0:31:49.59,Default,,0,0,0,,所以这样左左就可以让他对任何的具有这个欧斯蒂姆类型的都定义了一个左佐这个成员函数
Dialogue: 0,0:31:49.59,0:32:04.28,Default,,0,0,0,,然后不管是SDGCout 还是一个STDFstorm ,或者是一个什么文件啊,字符串输出指定码都可以很小吗?
Dialogue: 0,0:32:04.28,0:32:08.51,Default,,0,0,0,,现在现在声音很小吗?
Dialogue: 0,0:32:11.68,0:32:33.77,Default,,0,0,0,,我看看哦,没录的,就是我再说一遍,就是刚才说就是用pretty function 可以打印出就是当前这个函数的名字和它的所有参数,包括模板的这个参数都能打印出来的
Dialogue: 0,0:32:34.10,0:32:40.08,Default,,0,0,0,,我是这个同学的名,嗯,刚才没录到
Dialogue: 0,0:32:42.86,0:32:47.56,Default,,0,0,0,,对呀,可以用那个剪辑软件什么的
Dialogue: 0,0:32:50.95,0:33:06.13,Default,,0,0,0,,然后然后就是继续刚才说就是有的同学说,哎呀,你们 C++ 怎么打印,有没有说这么累呀,我就直接把这个函数贴给他,他就闭嘴了,知道吧?
Dialogue: 0,0:33:07.14,0:33:12.44,Default,,0,0,0,,然后然后我们就是总结一下刚刚学到了什么
Dialogue: 0,0:33:12.44,0:33:20.55,Default,,0,0,0,,首先学到了类型,可以作为参数,然后整数也可以作为参数,浮点就不行
Dialogue: 0,0:33:20.55,0:33:30.05,Default,,0,0,0,,然后参数还可以有默认值,然后调用的时候通过间括号去调用TN在里面写参数
Dialogue: 0,0:33:30.05,0:33:39.83,Default,,0,0,0,,而如果这个括号里的参数类型正好是这个七里面有的话,那也可以省略,不写这个题
Dialogue: 0,0:33:40.16,0:33:46.56,Default,,0,0,0,,然后模板只有惰性编译和多次编译的特点
Dialogue: 0,0:33:46.56,0:33:53.22,Default,,0,0,0,,所谓多次就是这个T一旦变化的话,它就会重新的编一次
Dialogue: 0,0:33:53.22,0:33:54.61,Default,,0,0,0,,多一些呢
Dialogue: 0,0:33:54.61,0:34:03.21,Default,,0,0,0,,就是如果我这个函数从来没用到的话,它里面的内容编译器是不会去看的
Dialogue: 0,0:34:03.21,0:34:11.54,Default,,0,0,0,,他只大致瞄一眼,只要他只会去看到这个括号匹配的顺序,而不会具体看
Dialogue: 0,0:34:11.54,0:34:17.96,Default,,0,0,0,,就比如甚至我说字符串233他都不看懂了吗?
Dialogue: 0,0:34:19.32,0:34:28.60,Default,,0,0,0,,对啊,编辑软件,然后我们看自动类型推导,就是为什么需要auto 呢?
Dialogue: 0,0:34:28.60,0:34:33.48,Default,,0,0,0,,就我们上一节课不是讲到了那个线了吗?
Dialogue: 0,0:34:33.48,0:34:44.59,Default,,0,0,0,,它的返回是一个线的指针,而问题就是如果我的类名非常长,我还得写这个内容两遍
Dialogue: 0,0:34:46.28,0:34:57.59,Default,,0,0,0,,总之就是如果我们因为我已经知道michael 的返回,这个,我为什么不把它简写为auto 呢?
Dialogue: 0,0:34:57.59,0:35:06.20,Default,,0,0,0,,然后这样auto 就只要写一遍了,它会根据等号右边的词返回什么类型来判定
Dialogue: 0,0:35:06.20,0:35:12.31,Default,,0,0,0,,但因为它需要知道,等号右边的值就导致它不能分离
Dialogue: 0,0:35:12.31,0:35:18.15,Default,,0,0,0,,这个定义就是不能先凹凸P然后再P等于不可以
Dialogue: 0,0:35:20.49,0:35:52.70,Default,,0,0,0,,然后还有一个问题就是他不能用在内层原理,我也不知道为什么,总之他就是不让嗯,然后它还可以用于证明函数的返回定义变量是auto p 等于这个这个它会直接根据turn 右边的类型来决定你这个auto 变成就他也不需要写两遍了,但他的问题就是你要注意这三点
Dialogue: 0,0:35:54.11,0:36:07.21,Default,,0,0,0,,第一,如果函数有多条return 的话,所有的return 第11次,就比如我先是return 一个make share 的A后面又是F一个语句
Dialogue: 0,0:36:07.21,0:36:19.44,Default,,0,0,0,,什么return 的B那就不能通过auto ,你得自己自己写一个他们这两个返回分共用的类型,否则他又出错了
Dialogue: 0,0:36:19.77,0:36:29.34,Default,,0,0,0,,然后还有一点就是如果你函函数里没有return 语句,它很聪明,它就自动把凹凸推断为one
Dialogue: 0,0:36:31.07,0:36:36.47,Default,,0,0,0,,就比如这个去掉的话,那这个就是我也不会去返回就行了
Dialogue: 0,0:36:37.07,0:36:58.24,Default,,0,0,0,,不是,我跟你说,就只要你把一个函数写在另一个函数的同一同一个文件里,它都可以那里这个音量我告诉你,我就告诉你这个东西,这个东西就是个垃圾,一点用都没有
Dialogue: 0,0:36:58.24,0:37:02.18,Default,,0,0,0,,它已经它已经是上个时代的产物了
Dialogue: 0,0:37:02.18,0:37:10.33,Default,,0,0,0,,现在编译器都很聪明,它能够自动决定什么时候要优化,什么时候不要优化
Dialogue: 0,0:37:11.39,0:37:15.03,Default,,0,0,0,,就那年他已经不受你控制了好吗?
Dialogue: 0,0:37:15.03,0:37:21.55,Default,,0,0,0,,就不是你说他要优化,他就说他很智能,他他自动判断要不要
Dialogue: 0,0:37:21.55,0:37:25.98,Default,,0,0,0,,那你看像这种大的函数,它就不会那里了
Dialogue: 0,0:37:25.98,0:37:34.32,Default,,0,0,0,,哪怕你写个音量,它还是会生成一个函数,只不过这个函数是static 了,你知道吧?
Dialogue: 0,0:37:36.64,0:37:49.20,Default,,0,0,0,,然后还有一个很大的问题,就是如果你这个函数定义在另一个文件,那你证明auto funk 后面直接两个分号的话,它就出错了
Dialogue: 0,0:37:49.20,0:37:54.84,Default,,0,0,0,,因为编译器得看得到的内容,他才能决定auto 是怎么样
Dialogue: 0,0:37:54.84,0:37:59.21,Default,,0,0,0,,所以如果你分离的话,那它就不能凹凸了
Dialogue: 0,0:37:59.54,0:38:14.17,Default,,0,0,0,,所以说我们这这一节课讲的模板猿编程,很大程度上你觉得就是很大程度上说就是你最好不要分多稳健
Dialogue: 0,0:38:14.54,0:38:20.03,Default,,0,0,0,,你要用模板的话,就尽量不要分离了,知道吧?
Dialogue: 0,0:38:20.63,0:38:31.09,Default,,0,0,0,,他们这些面试官,你开除他们,不是他们开除你啊,这些面试官就是智障,知道吗?
Dialogue: 0,0:38:31.09,0:38:51.03,Default,,0,0,0,,他们学的是上世纪的教材,就现在这个in line 和status 是一个意思,它只能就是让一个函数变成statement ,而不能让它就强制它音量是没有用的,是没有用的
Dialogue: 0,0:38:51.40,0:38:55.66,Default,,0,0,0,,现在编译器都是自动决定要不要音量的
Dialogue: 0,0:38:55.66,0:39:00.93,Default,,0,0,0,,当然音量对于变量它有另一个作用,就是它会变成
Dialogue: 0,0:39:01.26,0:39:05.22,Default,,0,0,0,,总之它就对于函数已经没有任何意义
Dialogue: 0,0:39:05.22,0:39:14.90,Default,,0,0,0,,它不是原来那个意义了,它编译器要不要内联,就是只要你把它放在同一个文件里,它就会内联
Dialogue: 0,0:39:15.23,0:39:27.03,Default,,0,0,0,,当然他也可能不那天关键的问题是你要放在同一个文件里,他看得到你的声明和定义,他才能帮您内联呀
Dialogue: 0,0:39:27.53,0:39:41.38,Default,,0,0,0,,当然如果你分了1万 ,那可以用一种叫link time optimization ,也就是在链接的时候,让链接是让链接器看看能不能帮你内联掉
Dialogue: 0,0:39:41.38,0:39:50.25,Default,,0,0,0,,但是这样内联出来的效果就没直接在一个问题很大,那年的问题很大
Dialogue: 0,0:39:50.25,0:39:56.52,Default,,0,0,0,,但是因为这个东西的这个关键字已经没有用了,知道吗?
Dialogue: 0,0:39:56.52,0:40:05.56,Default,,0,0,0,,内联是编译器自动判断要不要内连的这个东西,它它已经是一个非关键词
Dialogue: 0,0:40:05.56,0:40:21.06,Default,,0,0,0,,这个东西就跟就跟什么东西一样知道啊,就是有一个这个很沙雕的关键字,它的功能是说,哎呀,编译器请你把哎这个东西放在寄存器里吧,这样更快
Dialogue: 0,0:40:21.59,0:40:30.81,Default,,0,0,0,,你想多了,现在编译器就算你不声明为register ,它也会自动帮你优化为一个寄存器里的
Dialogue: 0,0:40:30.81,0:40:51.90,Default,,0,0,0,,就你不需要自己去说,哎呀,这个这个变量我想让它变快,编译器它到什么变量需要被优化,你不需要再去写register in one 这些商标关键字了,已经被废除了,嗯,明白吧?
Dialogue: 0,0:40:51.90,0:40:56.04,Default,,0,0,0,,总之现在就是不是说到返回值嘛
Dialogue: 0,0:40:56.04,0:41:06.97,Default,,0,0,0,,还有一种类型就是加一个N的符号,这个其实和C语言的指针一样,它可以引用一个对象
Dialogue: 0,0:41:07.77,0:41:11.74,Default,,0,0,0,,就是就是怎么说呢?
Dialogue: 0,0:41:11.74,0:41:20.86,Default,,0,0,0,,就是F等于X的时候,他不是把X的值给了瑞弗,还是把X的地址给了瑞
Dialogue: 0,0:41:21.19,0:41:34.41,Default,,0,0,0,,所以这个如果我写入ZF等于42的话,这时候X也会变成42 ,也会变成12啊,这里打错了,应该是024的
Dialogue: 0,0:41:34.85,0:41:47.75,Default,,0,0,0,,总之就是就是ZF等于十二之后,因为ZF和X是引用了同一个变量,所以写中ZFX也会被写入
Dialogue: 0,0:41:47.75,0:41:52.51,Default,,0,0,0,,同理X被写入之后,ZF也会改变它的值
Dialogue: 0,0:41:52.51,0:41:59.51,Default,,0,0,0,,它们引用了同一个对象嗯,引用的本质和C里面的指针一样
Dialogue: 0,0:41:59.51,0:42:07.22,Default,,0,0,0,,只不过它是把这些S符号乘符号给自动帮你去掉了,明白吗?
Dialogue: 0,0:42:07.22,0:42:08.32,Default,,0,0,0,,明白吗?
Dialogue: 0,0:42:08.90,0:42:13.77,Default,,0,0,0,,就是他是一个语法堂,实际和指针一样的
Dialogue: 0,0:42:14.66,0:42:36.30,Default,,0,0,0,,然后如果说inter 和等于inter 乘,那inter constant 层和就等于inter constant 层,它是一个常引用,就是说它不能被写入,有时候更安全跟一些就知道它可以被优化
Dialogue: 0,0:42:36.30,0:42:55.34,Default,,0,0,0,,就比如现在我打印X是2 33 ,然后X等于1024以后ref 它虽然是常用,但它因为引用了X呀,它会自动更新合成和X的时候我们就可以了
Dialogue: 0,0:42:56.42,0:43:02.11,Default,,0,0,0,,对对,热敷的话它有一个缺陷,就是它必须被初始化
Dialogue: 0,0:43:02.11,0:43:19.36,Default,,0,0,0,,如果你只写income 和ref 之间的一个分号款就出错了,因为它必须得指向一个什么东西呀,就是这是编译器防止你犯错,就是引用它是没有空的这个概念的
Dialogue: 0,0:43:19.36,0:43:20.69,Default,,0,0,0,,但指针用的
Dialogue: 0,0:43:21.41,0:43:34.42,Default,,0,0,0,,然后然后刚才说了自动类型推导,自动类型推导也可以用oppo 和来表示它是自动推导为引用类型
Dialogue: 0,0:43:34.42,0:43:42.66,Default,,0,0,0,,就比如我X是inter 的话,然后统和就会变成嗯这样
Dialogue: 0,0:43:42.66,0:43:51.41,Default,,0,0,0,,如果你这里是一个很复杂的类型的话,那它就能帮你简化,比如factor 之类的
Dialogue: 0,0:43:51.91,0:44:01.23,Default,,0,0,0,,然后当然auto 也可以用常引用,用auto constant 和就可以实现变成一层抗组合方案
Dialogue: 0,0:44:01.76,0:44:06.34,Default,,0,0,0,,什么呢?
Dialogue: 0,0:44:06.34,0:44:18.34,Default,,0,0,0,,叫cos ,no case , 你要cost case ,但是怎么样用cross the case 的确是可以绕开绕开这个count 的问题
Dialogue: 0,0:44:18.75,0:44:25.62,Default,,0,0,0,,但是这样不就和你的安全背道而驰了吗?
Dialogue: 0,0:44:25.95,0:44:38.01,Default,,0,0,0,,所以还是尽量不要用它吧,然后函数它也可以返回引用函数返回引用也可以自动的
Dialogue: 0,0:44:38.01,0:44:53.46,Default,,0,0,0,,比如就是设计模式里有一种叫懒汉单利模式,就是单利模式有很多种,懒汉是一种它代表只有进入到这个函数里的时候,它这个才会被实例化
Dialogue: 0,0:44:53.46,0:45:07.59,Default,,0,0,0,,而 C++ 标准规定,就如果你一个函数里有一个static 变量,那这个static 的初始化是在你进入这个函数第一次进入的时候才会去初始化
Dialogue: 0,0:45:07.59,0:45:16.32,Default,,0,0,0,,所以这个其实是个懒代理模式,而不是一加载这个程序的时候就出发的
Dialogue: 0,0:45:19.23,0:45:26.99,Default,,0,0,0,,所以这样的话呢就只需要写一遍这个类型就返回的时候就不需要再写
Dialogue: 0,0:45:26.99,0:45:36.32,Default,,0,0,0,,然后我们就可以以这个函数的返回值将它视为一个对象这样去调用,但它已经变成了
Dialogue: 0,0:45:36.76,0:45:53.09,Default,,0,0,0,,然后这两个嗯这个有点难想,就是幼稚,这个是上一期不是说到了移动吗?
Dialogue: 0,0:45:53.09,0:45:59.09,Default,,0,0,0,,就是移动是用两个核表,然后就是什么叫移动呢?
Dialogue: 0,0:45:59.09,0:46:10.81,Default,,0,0,0,,就是把一个值移到另一个地方去,但是它的数量不变,因为另一个变为空了,然后就可以看一下这里的测试
Dialogue: 0,0:46:10.81,0:46:16.65,Default,,0,0,0,,比如A是可以写入的,所以它是一个单个核,就是引用
Dialogue: 0,0:46:16.65,0:46:28.85,Default,,0,0,0,,然后P呢就是它是乘以P也就是这个P的地址也是可以写入的,所以是引用,然后P括号A它也是可以引用的
Dialogue: 0,0:46:28.85,0:46:33.09,Default,,0,0,0,,然后一呢它是临时性存在于内存中的
Dialogue: 0,0:46:33.09,0:46:48.32,Default,,0,0,0,,就是说我这个语句执行完之后,这个一又不存在了,然后A加一也是的,A是存在于内存中,而A加一它只是为了调用test 而临时生成的一个值而已
Dialogue: 0,0:46:48.32,0:46:50.71,Default,,0,0,0,,所以它是一个幼稚引用
Dialogue: 0,0:46:51.36,0:46:59.89,Default,,0,0,0,,然后我们可以看到这里有三个重载,然后我们这一个个去调用它就会变成这三个重点
Dialogue: 0,0:46:59.89,0:47:04.40,Default,,0,0,0,,如果你不理解的话,直接跳过,因为老师也不如
Dialogue: 0,0:47:04.73,0:47:14.36,Default,,0,0,0,,然后coast 的作用就是之前不是说这个函数参数你可以用count 和病原拷贝嘛
Dialogue: 0,0:47:14.36,0:47:28.86,Default,,0,0,0,,那为什么我有时候写print 括号1 ,就比如括号3 ,这样也能通过明明我的三是一个双N的符号的柚子为什么能变成cos 引用呢?
Dialogue: 0,0:47:28.86,0:47:49.34,Default,,0,0,0,,而这个cos 的英文就不行了,因为编译器你开了一个洞,他说又只能够自动退化为intercom 的话,也就是说因为一样它只存在于内存中,所以说它变成一个不可变的引用是可以的
Dialogue: 0,0:47:50.67,0:48:03.38,Default,,0,0,0,,对呀,编译器开动很好笑啊,确实心压压又是喜欢这样不停的开动,然后就变成一门非常复杂的语言
Dialogue: 0,0:48:04.33,0:48:07.11,Default,,0,0,0,,总之这个是能通过的
Dialogue: 0,0:48:08.45,0:48:14.39,Default,,0,0,0,,然后小鹏老师在做window 的时候,发明了这个小工具
Dialogue: 0,0:48:15.41,0:48:28.77,Default,,0,0,0,,总之这个东西它就能够返回返回我那个那个那个这个模板参数T的那个那个那个类型名字
Dialogue: 0,0:48:28.77,0:48:37.42,Default,,0,0,0,,就比如我这里定一个红袖印腾的话,然后我这里就可以自动打印出int
Dialogue: 0,0:48:37.75,0:48:50.20,Default,,0,0,0,,总之总之就没有任何区别,没有任何区别,这个只是个人喜好问题
Dialogue: 0,0:48:50.63,0:48:59.08,Default,,0,0,0,,我喜欢写在后面,就比如这里你也看到了counts in the 和和in the council 和是等价的
Dialogue: 0,0:48:59.08,0:49:19.63,Default,,0,0,0,,然后这里搞了一个很复杂的,它和这个也是嗯然后还有一个 C++ 11 ,还是总之引入这就是他可以返回一个一个已经存在对象的类型
Dialogue: 0,0:49:19.63,0:49:30.48,Default,,0,0,0,,就如果我们溴碘client tap a 的话,因为A定义的时候是int ,所以说它也会告诉你s int 类型哦
Dialogue: 0,0:49:30.81,0:49:35.81,Default,,0,0,0,,然后C是一个cost 的引用,它也会自动变成
Dialogue: 0,0:49:35.81,0:49:42.76,Default,,0,0,0,,然后除了可以点collect 一个变量之外,也可以decline 一个表达式
Dialogue: 0,0:49:42.76,0:49:52.77,Default,,0,0,0,,就比如3.14加A因为A是整数,而这里有一个浮点,浮点加硬,它会自动提升到浮点
Dialogue: 0,0:49:52.77,0:49:55.83,Default,,0,0,0,,所以说这个会打印出浮点
Dialogue: 0,0:49:56.49,0:50:00.17,Default,,0,0,0,,我忘记截了,这里应该少一个float
Dialogue: 0,0:50:00.72,0:50:12.62,Default,,0,0,0,,总之然后这里是二是二,也是单独的一个inter ,然后and a 呢就代表取A的地址,所以自然是int 常类型啊
Dialogue: 0,0:50:12.62,0:50:22.55,Default,,0,0,0,,然后P括号0的话,因为P是一个指针的,所以P括号零它是指向一个可以写作的
Dialogue: 0,0:50:23.69,0:50:40.14,Default,,0,0,0,,然后然后最坑的一点来了,就是the collect type 括号A因为A定义为inter 而decline type 括号,括号A两层括号,它就会认为有一层括号,它这是一个表达式
Dialogue: 0,0:50:40.65,0:50:48.67,Default,,0,0,0,,也就是说它这个是decline type 变量名的语义,而这是definitely 表达式的语义
Dialogue: 0,0:50:48.67,0:50:57.51,Default,,0,0,0,,所以这时候他认为这个表达式是一个type ID不要理type ID
Dialogue: 0,0:50:57.51,0:51:07.85,Default,,0,0,0,,我告诉你type ID必须和有虚函数的类才能一起用type ID
Dialogue: 0,0:51:07.85,0:51:31.56,Default,,0,0,0,,就比如说就比如如果我只有这个A,然后我这speak 的B继承了A然后我这时候去看一个,比如说一个B然后你想啊A乘A等于UB我这时候type ID乘A它是不准的,它是不准的
Dialogue: 0,0:51:31.56,0:51:40.73,Default,,0,0,0,,就是它会返回给你一个它会返回给你一个A的type ID,而不是B的
Dialogue: 0,0:51:40.73,0:51:52.83,Default,,0,0,0,,如果你想让它实现多态,你可以这样给它任意一个我求函数,这样它才能变成B就是type ID
Dialogue: 0,0:51:52.83,0:51:58.47,Default,,0,0,0,,如果你没有完成的话,它不会自动去确定它
Dialogue: 0,0:51:58.47,0:52:04.11,Default,,0,0,0,,这是一个比如说从B转换到A它不确定的
Dialogue: 0,0:52:04.79,0:52:07.38,Default,,0,0,0,,对呀,就很懵逼
Dialogue: 0,0:52:07.71,0:52:12.43,Default,,0,0,0,,type ID它只有在你有虚函数的时候才起作用
Dialogue: 0,0:52:12.43,0:52:24.25,Default,,0,0,0,,如果你不起作用的话,如呃如果你没有虚寒速度话,它会变成你给他什么类型就什么类型到了吧
Dialogue: 0,0:52:28.87,0:52:41.79,Default,,0,0,0,,指针会有区别,指针的区别我告诉你是这个这个样子的
Dialogue: 0,0:52:41.79,0:52:51.33,Default,,0,0,0,,inter constant , 这个是有区别的,这两个是有区别的,这两个是有区别的
Dialogue: 0,0:52:51.33,0:52:57.20,Default,,0,0,0,,而这两个in the constant ,它还在乘前面,那就是没问题的
Dialogue: 0,0:52:57.20,0:53:21.82,Default,,0,0,0,,这两个是一样的,这个不一样,知道了吧,这个不一样,这两个一样的就是要看成是在抗生素左边还是右边,在右边的话就代表是这个成这个指针本身不能,而不是指针指向的位置,不能改到了吧,明白了吗?
Dialogue: 0,0:53:21.82,0:53:33.21,Default,,0,0,0,,明白了,扣一都不想换了,嗯,明白了吗?
Dialogue: 0,0:53:33.21,0:53:48.77,Default,,0,0,0,,就是这两个是我可以给你看一个例子啊,就是我告诉你一个秘密,就是C家家里有这么一个东西,你可以去玩一玩
Dialogue: 0,0:53:52.98,0:53:57.74,Default,,0,0,0,,就是你可以看到这是打印出哎呀,不要这些垃圾垃
Dialogue: 0,0:53:58.34,0:54:05.79,Default,,0,0,0,,然后你可以看到就是as some be in it ,也就是这两个类型是一样的
Dialogue: 0,0:54:06.32,0:54:17.30,Default,,0,0,0,,然后it 和cos 因为一不一样呢,他说不一样,然后in 的cos 和cos 硬点又不一样呢,他说哎一样的
Dialogue: 0,0:54:17.30,0:54:22.59,Default,,0,0,0,,然后怎么说in the cost 和cost in to the 是不是一样呢?
Dialogue: 0,0:54:22.92,0:54:24.26,Default,,0,0,0,,是一样的
Dialogue: 0,0:54:24.26,0:54:48.78,Default,,0,0,0,,那么我现在把cos 的一个位置移到陈后面呢,哎不一样了,懂了吧,你就多玩玩这个这个东西叫type traits ,你可以搜搜看看看一下这个看一下这个链接,农民伯伯的这个都明白了
Dialogue: 0,0:54:52.70,0:55:13.52,Default,,0,0,0,,然后还有一些就是就比如说比如我这里intercom 和inter 不同嘛,就是现在是不同的,我可以用STD,they move count 杠7 ,移除那个count,这样他们又相同
Dialogue: 0,0:55:13.52,0:55:15.29,Default,,0,0,0,,这也是个type trade
Dialogue: 0,0:55:17.24,0:55:28.56,Default,,0,0,0,,老哥,我在路上呢,待会儿你们就能看录播了,你看一下我B站空间呀,已经录了两期了
Dialogue: 0,0:55:29.40,0:55:34.59,Default,,0,0,0,,有问题吗?
Dialogue: 0,0:55:37.30,0:55:38.66,Default,,0,0,0,,有问题吗?
Dialogue: 0,0:55:38.66,0:55:53.01,Default,,0,0,0,,type of trees, 然后我这里还可以加个好,然后我再说SEMreference 杠T也能够自动把它变成一样的,明白吧?
Dialogue: 0,0:55:55.17,0:56:01.14,Default,,0,0,0,,所以decline type 经常和这个原目录count 和原目录reference
Dialogue: 0,0:56:01.14,0:56:19.87,Default,,0,0,0,,如果你想要简写这两个,其实可以合并成一个SGDK,它会自动把你所有的coast 和变成普通的inter,然后把你的int 方括号呢给退化成一嗯
Dialogue: 0,0:56:25.38,0:56:43.72,Default,,0,0,0,,然后然后就是 C++ 14引入我们的decline type auto on,嗯,它的作用就和decline type funk p 等于funk 一样,它可以把这里换成auto,你就不用把它写两遍了
Dialogue: 0,0:56:45.53,0:56:49.95,Default,,0,0,0,,那既然我有auto,为啥还要decline type auto 呢?
Dialogue: 0,0:56:49.95,0:56:54.37,Default,,0,0,0,,因为我的P可能返回了一个引用啊
Dialogue: 0,0:56:54.37,0:57:03.51,Default,,0,0,0,,如果你用的话,那P它就不再是引用,而是变成这个引用给点K之后的执法
Dialogue: 0,0:57:03.51,0:57:18.97,Default,,0,0,0,,所以点client type 它就是能够实现自动匹配,分成返回值,而不去点K它嗯点K就和我刚才说到了说到了这个点K是一个意思
Dialogue: 0,0:57:18.97,0:57:25.60,Default,,0,0,0,,就是如果上课返回一个in 的和的话,它会被自动点K为
Dialogue: 0,0:57:32.22,0:57:50.17,Default,,0,0,0,,088它和凹凸的区别就在于,就如果我写auto 和P等于饭卡,饭卡是一个返回十的函数,它就出错了
Dialogue: 0,0:57:50.50,0:57:58.66,Default,,0,0,0,,就是我必须放开得返回一个引用,它才不出错,而decline temp 它就能够自动匹配
Dialogue: 0,0:57:58.66,0:58:00.25,Default,,0,0,0,,你是不是引用?
Dialogue: 0,0:58:01.00,0:58:10.37,Default,,0,0,0,,如果你不是引用,它也能够自动变成int 的啊auto 和你就必须得返回引用,知道吧?
Dialogue: 0,0:58:10.76,0:58:29.86,Default,,0,0,0,,不是autos 会不会点K这个东西它只能匹配引用了,而declare time 它能够匹配你那个点K对我管它叫什么,但它其实是你真的解瘾,要用上嗯
Dialogue: 0,0:58:35.20,0:58:39.56,Default,,0,0,0,,然后就是刚才不是提到代理模式吗?
Dialogue: 0,0:58:39.89,0:58:51.02,Default,,0,0,0,,代理模式就是说我一个类里面有一个m internal class ,然后对我这个函数的调用都会转移到对它的调用
Dialogue: 0,0:58:51.99,0:58:57.98,Default,,0,0,0,,而它的返回值可能是常引用,也可能是可变引用
Dialogue: 0,0:58:57.98,0:59:05.62,Default,,0,0,0,,所以这时候我就可以用decline type auto ,就不需要再指明它是什么引用
Dialogue: 0,0:59:05.96,0:59:37.74,Default,,0,0,0,,然后就是说 C++ 最新引入的using 这个和type default 是一样的,只不过它顺序掉了掉,就之前是type def 类型make it 现在变成using make it 等于类型,他就更符合变量赋值的那种顺序关系就更直观了,但是也不一定强自己去用
Dialogue: 0,0:59:39.69,0:59:51.24,Default,,0,0,0,,然后它还有一个优点,就是对于函数的type def ,它的type def 就很烦,就必须得把类型名写在这个小括号里
Dialogue: 0,0:59:51.24,1:00:03.50,Default,,0,0,0,,然后它这样的话,它就可以写在前面,就他就成功的分离的质量看起来就更清楚,其实是很大的
Dialogue: 0,1:00:04.73,1:00:08.30,Default,,0,0,0,,然后来看点clay tap 有什么作用吧
Dialogue: 0,1:00:08.30,1:00:13.24,Default,,0,0,0,,就刚才不是说的模板函数可以部分特化了
Dialogue: 0,1:00:13.24,1:00:27.14,Default,,0,0,0,,然后这里我就部分特化了一个,and a 的就是说它可以把任意两个不同类型的vehicle 给加起来,然后加起来它返回什么呢?
Dialogue: 0,1:00:27.14,1:00:28.48,Default,,0,0,0,,要怎么算呢?
Dialogue: 0,1:00:28.48,1:00:38.69,Default,,0,0,0,,它返回的肯定是一个victor 吧,但这个victor 容器类型你知道嗯,这时候就得用上点client time
Dialogue: 0,1:00:39.02,1:00:48.97,Default,,0,0,0,,首先我创建一个T一的对象,然后再创一个T2的对象,然后将它们相加起来
Dialogue: 0,1:00:48.97,1:00:57.06,Default,,0,0,0,,这时候是一个值,然后我用decline type 获取这个值的类型,也就是T0
Dialogue: 0,1:00:57.06,1:01:14.76,Default,,0,0,0,,比如T一是int 的话,int 加上这个float ,那返回一个float 值,然后再用declare type 70就等于float ,所以它会自动返回一个float 的那个没喝汤
Dialogue: 0,1:01:14.76,1:01:26.77,Default,,0,0,0,,比如这样,然后它就能够自动把这个C其实是变成flow 的那个type name
Dialogue: 0,1:01:26.77,1:01:35.67,Default,,0,0,0,,你是说哪一个哦你是说哪一个,你是说class 那个吗?
Dialogue: 0,1:01:36.00,1:01:37.98,Default,,0,0,0,,你是说这个吗?
Dialogue: 0,1:01:38.60,1:01:40.43,Default,,0,0,0,,你是说这个吗?
Dialogue: 0,1:01:41.05,1:01:50.20,Default,,0,0,0,,对的,他是编译期确定的,就是刚才说的SDK啊,这些都是编译器确定的
Dialogue: 0,1:01:50.53,1:01:56.79,Default,,0,0,0,,你如果是说这个,那我告诉你他两个都可以用
Dialogue: 0,1:01:56.79,1:02:21.00,Default,,0,0,0,,然后你如果是说刚才那个就是如果你是说这个的话,嗯,那么我就告诉你就是我告诉你这个不是后面有个减T嘛,就是如果你不用这个减T,而是用的这个的话,那是要用的,那是要用的
Dialogue: 0,1:02:21.65,1:02:23.90,Default,,0,0,0,,呦,烦死了,这边一起
Dialogue: 0,1:02:23.90,1:02:29.91,Default,,0,0,0,,如果你没有写减T的话,如果你写了减T那就不需要用
Dialogue: 0,1:02:29.91,1:02:32.42,Default,,0,0,0,,这是 C++ 14新增的
Dialogue: 0,1:02:32.42,1:02:38.43,Default,,0,0,0,,如果你还在用 C++ 11的话,你就得用这个超长的语法
Dialogue: 0,1:02:38.43,1:02:42.19,Default,,0,0,0,,而 C++ 14新增一个什么功能呢?
Dialogue: 0,1:02:42.52,1:02:53.84,Default,,0,0,0,,他可以用using 声明模板的别名,比如UZ点K杠T等于它其实是这样的
Dialogue: 0,1:02:53.84,1:02:59.54,Default,,0,0,0,,这样的话我就只需要写DKTit 就可以了
Dialogue: 0,1:03:00.78,1:03:05.97,Default,,0,0,0,,然后还有一个东西不能写type name ,就是STDS
Dialogue: 0,1:03:05.97,1:03:18.67,Default,,0,0,0,,sam 之前也是有这么一个沙雕的东西,之前是得这么写的,现在得这么写,现在这么写就可以了,知道吧?
Dialogue: 0,1:03:19.18,1:03:40.94,Default,,0,0,0,,以前是这么写的,然后现在是这么写的,以前以前以前的话是只有后面为type ,前面才需要加type name ,现在叠杠7-1简写,懂吧?
Dialogue: 0,1:03:41.30,1:03:52.06,Default,,0,0,0,,然后这个是decline type 的用途,然后你已经学会了这些自动推导工具是不是很方便
Dialogue: 0,1:03:52.39,1:03:54.24,Default,,0,0,0,,不理解吗?
Dialogue: 0,1:03:54.24,1:03:57.57,Default,,0,0,0,,那就不要用,然后跳过
Dialogue: 0,1:03:57.57,1:04:12.64,Default,,0,0,0,,然后就是今天的第二个主题,还我去这什么情况,这个什么情况错了,搞错了
Dialogue: 0,1:04:13.49,1:04:18.11,Default,,0,0,0,,客人他是来,然后就你知道吗?
Dialogue: 0,1:04:18.11,1:04:25.61,Default,,0,0,0,,函数也是可以作为参数的,也就是说函数它只不过是类型的一种
Dialogue: 0,1:04:25.61,1:04:36.80,Default,,0,0,0,,比如说我这里写cotton boy 的饭卡,也就是把一个函数作为参数啊,它其实是传了这个函数呢
Dialogue: 0,1:04:36.80,1:04:41.49,Default,,0,0,0,,其实第嗯看看有问题吗?
Dialogue: 0,1:04:41.49,1:04:48.43,Default,,0,0,0,,模板早就讲过了,杠V是一个简写呀,就是这个东西的简写
Dialogue: 0,1:04:48.43,1:05:01.16,Default,,0,0,0,,这个杠题就是这个的简写,冒号冒号temp c 加加是引入杠T杠V这些简写就不需要反复的去写,更volunteer 了
Dialogue: 0,1:05:01.16,1:05:02.03,Default,,0,0,0,,懂了吗?
Dialogue: 0,1:05:02.53,1:05:11.81,Default,,0,0,0,,老早讲了,自己看录播,然后函数作为参数也可以有参数
Dialogue: 0,1:05:11.81,1:05:21.85,Default,,0,0,0,,就比如worried funk int 就是代表这个是一个接受in 的参数的函数,作为餐对吧?
Dialogue: 0,1:05:21.85,1:05:35.89,Default,,0,0,0,,比如paint number 是一个接受internet 参考,所以它可以作为这个接受inter 参数的函数的参数啊,有问题吗?
Dialogue: 0,1:05:36.28,1:05:41.90,Default,,0,0,0,,就是这个word panda ,那么它的类型是匹配的,所以可以传入
Dialogue: 0,1:05:41.90,1:05:56.45,Default,,0,0,0,,然后在这里面也可以去调用这个饭卡,第一次调用按零作为参数,第二次按一作为参数,嗯,然后就变成number 0number1
Dialogue: 0,1:05:56.45,1:06:13.13,Default,,0,0,0,,因为这里是说的number ,然后函数就是刚才不是这样嘛,写起来很别扭,所以就可以利用刚刚写的模板函数,就把这个phone 作为模板参数,让它自动去匹配嘛
Dialogue: 0,1:06:13.13,1:06:21.74,Default,,0,0,0,,这样的话有一个好处,就是刚才必须飞的,那么这里为income 才能作为参数传递
Dialogue: 0,1:06:21.74,1:06:44.32,Default,,0,0,0,,如果我又不漏了的话,他刚刚是传不进去的,但这里就可以因为方程式模板他出来,所以他可以是任何类型,不用不用就是 C++ 有一个特色,就是函数和函数指针都可以用这个来表示
Dialogue: 0,1:06:44.32,1:06:50.21,Default,,0,0,0,,如果你这样表示,其实和函数指针是一样的,它是等价的
Dialogue: 0,1:06:50.62,1:06:59.51,Default,,0,0,0,,然后这样的话它就会自动生成两个call 探索
Dialogue: 0,1:06:59.51,1:07:11.86,Default,,0,0,0,,第一个用于web blood float ,第二个web point 的那个每一次都会适配一遍,这样的话是可以自动优化的
Dialogue: 0,1:07:13.55,1:07:28.41,Default,,0,0,0,,等到了他,然后然后就是刚刚不是说必须用一个外部全局的函数作为它的参数嘛,这样很不方便
Dialogue: 0,1:07:28.41,1:07:34.19,Default,,0,0,0,,如果我们直接把这个东西写到这里面就方便了
Dialogue: 0,1:07:34.19,1:07:43.73,Default,,0,0,0,,所以说C11引入了lambda 表达式,它这样的话就相当于直接在提升一个买份卡
Dialogue: 0,1:07:45.23,1:07:53.41,Default,,0,0,0,,就是说这个和直接作为一个全局函数的mysql 是等价的
Dialogue: 0,1:07:53.41,1:07:57.04,Default,,0,0,0,,它的好处是它不会污染全局
Dialogue: 0,1:07:57.56,1:08:10.06,Default,,0,0,0,,也就是呃就比如我这个还是一个买份额,另一个又一个买份卡,那不就冲突了,现在直接写在里面,我每一个函数都能有一个买份子哈
Dialogue: 0,1:08:10.52,1:08:18.18,Default,,0,0,0,,呀没电了,必须得拆哟,现在有杂音吗?
Dialogue: 0,1:08:19.57,1:08:21.02,Default,,0,0,0,,没有吧
Dialogue: 0,1:08:23.07,1:08:35.00,Default,,0,0,0,,然后就是量不大,表达式的语法就是一个空的大括号,开头后面和普通函数就一样了
Dialogue: 0,1:08:35.00,1:08:40.81,Default,,0,0,0,,就它只是一个空括号开头后面和普通函数一样
Dialogue: 0,1:08:40.81,1:08:55.72,Default,,0,0,0,,然后先是参列表啊,然后是这个呃那个快速提呀,就然后lambda 就是刚才不是说它是以公众号,那不是没有办法指定返回值了吗?
Dialogue: 0,1:08:55.72,1:09:18.84,Default,,0,0,0,,可以呢,他可以用这个一用这样这样,然后后面弄一个箭头就代表着啊,我是相当于it twice 括号in it n 括号这样嗯就他可以在后面后置返回值,明白了吧?
Dialogue: 0,1:09:18.84,1:09:33.27,Default,,0,0,0,,对呀,XFCE比如这样我要返回一个int 类型的话,那就写N乘2 ,N乘2也是硬的
Dialogue: 0,1:09:33.27,1:09:59.87,Default,,0,0,0,,但它还有一个智能的点,就是如果你这里有只有一个return 的话,它可以不用写这个箭头,它会自动判断哦,原来你N是整数,二是整数,那相乘也是整数,然后它就会自动认为它这个串是会返回硬盘了,这个和我们函数分明为返回值是一样的
Dialogue: 0,1:10:00.68,1:10:02.81,Default,,0,0,0,,我先暂停一下,待会儿
Dialogue: 0,1:10:03.91,1:10:17.49,Default,,0,0,0,,好,刚才说这个那么大的好处是,它可以就是证明在局部它还有一个什么好处,它可以捕获我局部的变量
Dialogue: 0,1:10:17.97,1:10:37.15,Default,,0,0,0,,就比如这样他其实就会把这个补货为这个里面,然后call transfer 的话,它这里面虽然没有给把这个frank 传给call transfer ,但是frank 已经作为引用创始人了
Dialogue: 0,1:10:37.15,1:10:38.38,Default,,0,0,0,,也就是fun
Dialogue: 0,1:10:38.38,1:10:50.06,Default,,0,0,0,,它其实那次一个指向的指针,然后我调用的时候,它就先进入到这里,然后它会查找外面的fank
Dialogue: 0,1:10:50.46,1:11:01.04,Default,,0,0,0,,这种就是你可以搜一下,它就叫做B包,像javascript 这种它都有B包的功能
Dialogue: 0,1:11:02.24,1:11:10.68,Default,,0,0,0,,然后我们 C++ 现在终于也有弊包了,是不是很方便?
Dialogue: 0,1:11:10.68,1:11:23.26,Default,,0,0,0,,然后然后他还有一个一个功能,就是用这个括号和可以捕获这个frank 变量嘛
Dialogue: 0,1:11:23.26,1:11:27.75,Default,,0,0,0,,它这frank 变量不仅可以读,还可以写入
Dialogue: 0,1:11:27.75,1:11:58.02,Default,,0,0,0,,就比如我可以把做一个content 变量,然后我写段子,这里不是捕获了这个捕获可不是常引用哦,是可变引用哦,所以这里counter 加加,而这里调用混合调了两次,就相当于给count 加了两次,从而他这里就变成调用了两次了啊,是不是很方便发现?
Dialogue: 0,1:11:59.85,1:12:04.48,Default,,0,0,0,,对呀对呀,我马上跟你讲了呀,你急啥了?
Dialogue: 0,1:12:05.23,1:12:21.82,Default,,0,0,0,,这个和它有一个缺点,就是你不要叫我马上跟你讲,然后就slam 的还有一个希望,就是你最好作为常引用传递哦
Dialogue: 0,1:12:21.82,1:12:25.99,Default,,0,0,0,,为什么要作为常引用传递呢?
Dialogue: 0,1:12:26.32,1:12:30.37,Default,,0,0,0,,就是因为混合的大小是16字节
Dialogue: 0,1:12:30.37,1:12:37.62,Default,,0,0,0,,如果你不穿长饮用,它就会拷贝一遍,就有可能会造成开槽
Dialogue: 0,1:12:37.62,1:12:40.73,Default,,0,0,0,,所以用长饮用也可以避免
Dialogue: 0,1:12:40.73,1:12:43.83,Default,,0,0,0,,这个为什么是十六之前呢?
Dialogue: 0,1:12:43.83,1:12:53.16,Default,,0,0,0,,其实就是因为这里捕获了frank ,也捕获了counter 变量,它其实存了这两个东西的指针
Dialogue: 0,1:12:53.16,1:12:57.12,Default,,0,0,0,,你跟我说一个指针不是八字节吗?
Dialogue: 0,1:12:57.12,1:13:00.51,Default,,0,0,0,,那不会两个就是16字节了
Dialogue: 0,1:13:00.51,1:13:04.46,Default,,0,0,0,,所以这个这个其实有16字节的
Dialogue: 0,1:13:04.46,1:13:09.97,Default,,0,0,0,,如果你能避免拷贝,就避免一下,对吧?
Dialogue: 0,1:13:11.85,1:13:23.82,Default,,0,0,0,,你急啥了,你都懂了,你就不用上了嘛啊是吧,你还来上,你就你知道会开的作用一
Dialogue: 0,1:13:23.82,1:13:37.11,Default,,0,0,0,,然后刚才他不是说作用一嘛,就是那么大,可以作为返回值的作为参数是用temporary 的声明作为返回值
Dialogue: 0,1:13:37.11,1:13:44.17,Default,,0,0,0,,必须要用oppo ,这是因为lambda 的表达式的类型永远是一名的
Dialogue: 0,1:13:44.17,1:13:48.29,Default,,0,0,0,,我必须用auto 才能推导出它的类型
Dialogue: 0,1:13:48.98,1:14:01.01,Default,,0,0,0,,就比如说make twice ,他创建了一个twice 这个函数在局部,然后返回出来,你再把这个量呢传给他也没问题
Dialogue: 0,1:14:01.41,1:14:03.68,Default,,0,0,0,,然后作为返回值
Dialogue: 0,1:14:03.68,1:14:13.11,Default,,0,0,0,,然后我们现在突然想就是能不能make transfer ,就是把这个参数作为绑定呢?
Dialogue: 0,1:14:13.85,1:14:24.74,Default,,0,0,0,,那是这样一试试下来,发现出了个问题,就是这个掉了以后,为啥变成32764呢?
Dialogue: 0,1:14:24.74,1:14:35.58,Default,,0,0,0,,这是因为这个函数一旦调用完,已经退出了这个thank 它它他已经在站上已经销毁了
Dialogue: 0,1:14:35.58,1:14:57.88,Default,,0,0,0,,也就是说我那个团子退出以后,这个团子你不是还存了一个纸箱,fake 已用嘛,而这个fake 所在的地址,因为make time 的退出而已经失效了,所以你再去用它去调用的话,就会嗯就会变成一个空悬指针
Dialogue: 0,1:14:57.88,1:15:07.38,Default,,0,0,0,,所以粪块的大小为八,也预示着这里也就是预示着这里其实成了一个指向fan ,可能比分
Dialogue: 0,1:15:07.81,1:15:14.41,Default,,0,0,0,,然后这个指针因为退出,所以而失效了
Dialogue: 0,1:15:14.41,1:15:27.79,Default,,0,0,0,,要解决这个问题很简单,把这个括号和换成括号等于然后就可以把frank 作为一个值给存进去,而不是把frank 的指针存在
Dialogue: 0,1:15:27.79,1:15:44.81,Default,,0,0,0,,这样我们也可以看到funk 的大小变成了4 ,因为硬成大小是四嘛,原来是成了一个指针,指针为8 ,现在变为四,就说明它是直接把这样可能只给穿进去
Dialogue: 0,1:15:45.81,1:15:51.21,Default,,0,0,0,,然后但是它会造成变量的拷贝
Dialogue: 0,1:15:51.21,1:15:59.99,Default,,0,0,0,,所以如果你没有空悬指针的问题,就还是尽量用这个盒子,它不需要拷贝哦
Dialogue: 0,1:16:00.52,1:16:10.31,Default,,0,0,0,,所以说用和它就有一个问题,就是你要保证lambda 的生命周期不长于它所有引用的寿命
Dialogue: 0,1:16:10.31,1:16:15.76,Default,,0,0,0,,这在我们上一课也讲过了,就是管理生命周期嘛
Dialogue: 0,1:16:15.76,1:16:27.24,Default,,0,0,0,,如果你你想偷懒,你不想管这么多,你可以用等于配合把fake 变成一个共享指针,也就是shared pointer
Dialogue: 0,1:16:27.24,1:16:29.54,Default,,0,0,0,,这样lambda 能活多久?
Dialogue: 0,1:16:29.54,1:16:34.13,Default,,0,0,0,,这个fake 就能活多久,它就减轻你的负担
Dialogue: 0,1:16:34.13,1:16:39.30,Default,,0,0,0,,所以这个等于是能够和shell point 配合使用的
Dialogue: 0,1:16:40.10,1:16:48.13,Default,,0,0,0,,你看你不是还喜欢装病啊,现在不是有告诉你要用等于了吗?
Dialogue: 0,1:16:48.13,1:16:49.42,Default,,0,0,0,,你看对吧?
Dialogue: 0,1:16:49.42,1:16:53.36,Default,,0,0,0,,这样不就没必要进了,对吧?
Dialogue: 0,1:16:53.36,1:17:07.88,Default,,0,0,0,,然后刚才说到lambda 具有匿名的特性,他没办法声明为一个具体类型,就算周围输入也要用模板,但模板有什么特点呢?
Dialogue: 0,1:17:07.88,1:17:22.48,Default,,0,0,0,,它就不能分离声明和定义了嘛,所以用户需要分离,声明和定义可以用functionality 的头文件提供的SD级范围内模板
Dialogue: 0,1:17:22.48,1:17:29.64,Default,,0,0,0,,然后它括号里面写的是返回类型,然后括号里面这个是参数
Dialogue: 0,1:17:29.64,1:17:40.81,Default,,0,0,0,,就这样的话,它就是一个具体类型了,但它是有开销的,它的效率和虚函数是一样的
Dialogue: 0,1:17:40.81,1:17:47.24,Default,,0,0,0,,因为它的实现就用到虚函数,嗯,明白吗?
Dialogue: 0,1:17:47.24,1:17:50.50,Default,,0,0,0,,这个同学你明白了吗?
Dialogue: 0,1:17:50.50,1:17:57.47,Default,,0,0,0,,明白了,扣一没有优化啊,是不是没录到
Dialogue: 0,1:17:58.48,1:18:05.25,Default,,0,0,0,,总之总之呢就是可以用这个这个叫类型擦除技术
Dialogue: 0,1:18:05.25,1:18:17.61,Default,,0,0,0,,SDEfunction , 就可以把所有函数一切具有括号形式调用的函数,把它变成一个虚函数了
Dialogue: 0,1:18:17.61,1:18:25.04,Default,,0,0,0,,然后就可以还有一种类型擦除技术叫S7级
Dialogue: 0,1:18:25.04,1:18:30.46,Default,,0,0,0,,any 你可以去了解他能够擦除什么呢?
Dialogue: 0,1:18:30.46,1:18:58.90,Default,,0,0,0,,他能够把具体类型擦除,只保留拷贝,检过移动这些这些呃这些那个嗯这些周围虚函数嗯,怎么不说话了,你嗯然后就是如果有多个参数就在括号里用逗号分割就可以了
Dialogue: 0,1:19:00.02,1:19:05.38,Default,,0,0,0,,然后然后就是上个星期不是说他有很大开销嘛
Dialogue: 0,1:19:05.38,1:19:25.84,Default,,0,0,0,,所以说如果你的这个串子是一个无补货的,也就是说你是一个空的方括号,就可以让它退化为一个函数指针,就不需要分析容器,它是无状态的那样子,也就是说和一个函数等价
Dialogue: 0,1:19:26.41,1:19:37.13,Default,,0,0,0,,像一些C语言的API,比如p sleep 的at x 呢,它就是只能支持函数指针的
Dialogue: 0,1:19:37.13,1:19:42.10,Default,,0,0,0,,但是它们也有一个好处,它可以传一个void 的层类
Dialogue: 0,1:19:42.44,1:19:46.62,Default,,0,0,0,,这个类型就是他们认为的这个状态
Dialogue: 0,1:19:46.62,1:19:57.50,Default,,0,0,0,,而我们认为的状态可是直接分装到这个函数里就是矣的类型,就是直接把它分装到函数里面
Dialogue: 0,1:19:57.50,1:20:09.88,Default,,0,0,0,,所以说如果你要伺候C语言的一些,伺候一些C语言AGI就可以用这个无无补货的
Dialogue: 0,1:20:09.88,1:20:19.23,Default,,0,0,0,,这个叫什么无补货的这个呃这个人员补单,然后可以看到无补货的0.5档
Dialogue: 0,1:20:19.23,1:20:27.85,Default,,0,0,0,,它其实退化成一个函数指针,就和指针的大小一样,它指向是那个缝缝的入口
Dialogue: 0,1:20:28.52,1:20:39.64,Default,,0,0,0,,因为然后可以看分割线的开胶很大,它要32GG这里面就有它的续航数表之类的啊
Dialogue: 0,1:20:40.70,1:20:51.67,Default,,0,0,0,,然后来不到将模板呃,就是刚才不是说这个lambda 的参数列表为in 的方案
Dialogue: 0,1:20:51.67,1:21:08.44,Default,,0,0,0,,其实这个那么大函数也能够变成一个模板函数,只需要把这里声明为auto drink ,声明为auto 的量不大,就相当于twice twice with template
Dialogue: 0,1:21:08.44,1:21:23.22,Default,,0,0,0,,然后这个T作为template 的那个class t 这两个是等价的到了吧,但是他这样就简写,只需要一个auto ,也不要什么temp
Dialogue: 0,1:21:24.61,1:21:35.68,Default,,0,0,0,,但是这样有一个缺陷,就是他没办法做部分特化,就比如T变成SCDVXT这个lambda 就做不到了
Dialogue: 0,1:21:36.68,1:21:50.82,Default,,0,0,0,,对呀,你看还还作用于呢,什么叫相比于模板,你是说哪一个呀?
Dialogue: 0,1:21:51.57,1:21:54.67,Default,,0,0,0,,你是说哪一个是这个吗?
Dialogue: 0,1:21:56.10,1:22:02.57,Default,,0,0,0,,开销很大,就是它的开销和旭函数一样大
Dialogue: 0,1:22:02.93,1:22:14.39,Default,,0,0,0,,然后但奥拓因为刚才说它和temporary 的等价,所以模板函数的特性它也具有
Dialogue: 0,1:22:14.39,1:22:19.37,Default,,0,0,0,,也就是说刚才不是说引号字符串等于233
Dialogue: 0,1:22:19.37,1:22:24.35,Default,,0,0,0,,如果你真的在这里面写一个的话,它不会出错
Dialogue: 0,1:22:24.35,1:22:32.47,Default,,0,0,0,,因为你有一个auto 作为参数,它认为你是个模板函数,它也会具有重要性效果
Dialogue: 0,1:22:32.47,1:22:43.21,Default,,0,0,0,,然后它也有多次编译项目,就比如这里调用的是份和3.14 ,那它就会以float 作为参数实例化一遍
Dialogue: 0,1:22:43.21,1:22:57.74,Default,,0,0,0,,然后以21的话,它又会作为interscience 化一遍,就是它也有多次编译的像所以说如果你一直用模板或者这种兰姆达,它也会变慢
Dialogue: 0,1:22:58.78,1:23:26.04,Default,,0,0,0,,看看录下来没有录了,然后就是说一下现在还没完成落地C加一下20 ,它和那个就是它可以让函数也可以用上,这样写起来就不用先template classroom 了再混合了就可以直接这样写,是不是很方便
Dialogue: 0,1:23:26.04,1:23:48.29,Default,,0,0,0,,然后对于有些比如我需要在lambda 里匹配为SGdevelop 这个策划的话,他也允许他也允许我这样写,就是直接在这里弄个间括号,他就等教育直接弄个template ,结果好,所以C3320还是有很多
Dialogue: 0,1:23:48.29,1:23:59.28,Default,,0,0,0,,总之就是在作业,你也可以这样,前提是你有相应的编译器能够编译的话,你也可以用哦
Dialogue: 0,1:24:01.11,1:24:04.20,Default,,0,0,0,,然后就是lambda 的一个用途
Dialogue: 0,1:24:04.20,1:24:11.24,Default,,0,0,0,,就这里我搞了一个假装非常高端的,就是外面来的一个函数
Dialogue: 0,1:24:11.24,1:24:24.47,Default,,0,0,0,,然后我循环了32次,然后每一次呢我先把I这个整数给调用到一个返回值,然后再把I加0.5作为返回值
Dialogue: 0,1:24:24.47,1:24:27.85,Default,,0,0,0,,这种在异步编程里非常常见
Dialogue: 0,1:24:27.85,1:24:30.10,Default,,0,0,0,,什么叫异步编程呢?
Dialogue: 0,1:24:30.10,1:24:41.08,Default,,0,0,0,,就是你给调用一个函数,它不是直接把数据返回给你,而是让这个函数接受一个函数作为参数
Dialogue: 0,1:24:41.08,1:24:48.06,Default,,0,0,0,,而这个接受作为参数的函数,它他来替代这个来看语句
Dialogue: 0,1:24:48.06,1:24:57.27,Default,,0,0,0,,也就是说当我得到一个数据的时候,我就去调用一个调用一下用户给的这个函数
Dialogue: 0,1:24:57.27,1:25:02.14,Default,,0,0,0,,然后用户给的函数是用一个lambda 来表示的
Dialogue: 0,1:25:02.14,1:25:06.74,Default,,0,0,0,,这里又用到我们刚刚说的type of treats 技术
Dialogue: 0,1:25:06.74,1:25:16.22,Default,,0,0,0,,首先这个X它是一个auto com 整合,那么它会实际化两遍,一种是按inter 实例化,一种是按float
Dialogue: 0,1:25:16.22,1:25:32.72,Default,,0,0,0,,而如果你直接写点client type x 的话,因为这是oppo ,所以它会变成float 的和所以我们可以用点K把抗复合去掉,变成干净的float ,然后float 判断是不是float
Dialogue: 0,1:25:32.72,1:25:37.16,Default,,0,0,0,,如果是float ,我就把它加到float 的这个对面
Dialogue: 0,1:25:37.16,1:25:50.23,Default,,0,0,0,,然后如果是个int 就加了in 的对面,然后因为这个SMV和点K他们都是变异期能够决定的,所以我可以加上抗诉
Dialogue: 0,1:25:50.23,1:25:54.87,Default,,0,0,0,,X怕嗯声音很小吗?
Dialogue: 0,1:25:55.97,1:25:58.91,Default,,0,0,0,,声音很小吗,很小吗?
Dialogue: 0,1:25:59.56,1:26:03.46,Default,,0,0,0,,喂喂喂,还早吗?
Dialogue: 0,1:26:04.10,1:26:17.25,Default,,0,0,0,,然后这这个这个就是刚刚说过了,然后lambda 还有一个用途,就是它不一定是延迟求或者作为参数,它可以立即求值
Dialogue: 0,1:26:17.25,1:26:25.82,Default,,0,0,0,,就是在我那么大括号结束之后立即去调用它,这有一个什么好处呢?
Dialogue: 0,1:26:25.82,1:26:30.33,Default,,0,0,0,,就之前我们都是向外部定一个泛的变量
Dialogue: 0,1:26:30.33,1:26:41.73,Default,,0,0,0,,就是比如我如果找到了,那就先把这个饭放着,等于I然后bring ,然后没找到又放着等于负一,然后就很麻烦
Dialogue: 0,1:26:41.73,1:26:54.86,Default,,0,0,0,,但有了那么大之后,我们可以直接利用return 自带black 效果的特点,然后就可以实现既break 又复制的效果
Dialogue: 0,1:26:55.45,1:27:08.80,Default,,0,0,0,,就是局部函数嗯,怎样点K可以去掉引用,也可以去掉,count 也可以去掉速度的那个括号
Dialogue: 0,1:27:13.73,1:27:17.11,Default,,0,0,0,,总之这样非常方便
Dialogue: 0,1:27:17.83,1:27:24.13,Default,,0,0,0,,然后lambda 还有一个用途,就是它可以实现匿名
Dialogue: 0,1:27:24.13,1:27:31.18,Default,,0,0,0,,递归要实现匿名呢首先把亮度呢自己作为自己的参数传递去
Dialogue: 0,1:27:31.18,1:27:40.12,Default,,0,0,0,,然后你这样oppo DFS等于这个DF作为参数,这样它就可以实现自己调用自己
Dialogue: 0,1:27:40.52,1:27:53.56,Default,,0,0,0,,但是这样一个缺点就是你必须声明它返回什么类型,否则它就没法推断这个在reno 中也用到了
Dialogue: 0,1:27:54.87,1:28:09.48,Default,,0,0,0,,然后你已经学会了能不能表达是嗯首先laughter 作为餐户是用template ,然后放个costs 和然后呢,作为返回值呢就证明为凹凸
Dialogue: 0,1:28:09.48,1:28:17.89,Default,,0,0,0,,然后如果你需要分离生命和定义,但是会牺牲性能,那你就实体机方可选
Dialogue: 0,1:28:17.89,1:28:25.47,Default,,0,0,0,,如果你想让量的座位参数,你通常会用and 来捕获引用作为返回值
Dialogue: 0,1:28:25.47,1:28:35.29,Default,,0,0,0,,因为量不大的生命周期会比较比这个引用长,所以你得用括号等于来作为值来补货
Dialogue: 0,1:28:35.29,1:28:42.31,Default,,0,0,0,,其实连不到,还有别的语法,但是因为不常用,所以就不讲了
Dialogue: 0,1:28:43.47,1:28:52.87,Default,,0,0,0,,然后讲一下就是这些新增的这些容器箭头函数
Dialogue: 0,1:28:52.87,1:29:08.73,Default,,0,0,0,,对呀,是的,新增的容器中有一个是突破,就是以前C他不是有个ST一片嘛,但片只能用两个多了,它就不行
Dialogue: 0,1:29:08.73,1:29:17.29,Default,,0,0,0,,所以说C它将实际引不是引入了变长的那个模板参数嘛,它就借此来使用trouble
Dialogue: 0,1:29:17.29,1:29:30.01,Default,,0,0,0,,然后trouble 的这个监控号,你可以有变长的数量,也就是只有一个也可以,零个也可以有很多个也可以就不限制于两个了
Dialogue: 0,1:29:30.34,1:29:39.38,Default,,0,0,0,,然后你这个要获取它的第一个值呢,也不用two point ,也算死它了,而是用STDget 的括号0
Dialogue: 0,1:29:39.38,1:29:44.41,Default,,0,0,0,,它这个返回呢是一个硬层类型的引用,就是突破
Dialogue: 0,1:29:44.41,1:29:50.70,Default,,0,0,0,,因为突破是一个引用嘛,所以它返回来的也是一个引用,对吧?
Dialogue: 0,1:29:52.77,1:30:00.74,Default,,0,0,0,,然后这样就可以解包一个出口,但是这样好像蛮麻烦的,我们可以这样化解
Dialogue: 0,1:30:00.74,1:30:06.65,Default,,0,0,0,,首先 C++ 17它的构造函数也可以自动推断类型了
Dialogue: 0,1:30:06.65,1:30:18.40,Default,,0,0,0,,所以说采用ST0tool括号,然后它会自动根据你这几个参数是啥类型来来决定two pod 间括号里是啥参数
Dialogue: 0,1:30:18.40,1:30:26.61,Default,,0,0,0,,然后这里因为它get 不是返回引用类型嘛,它能够自动推断也用上了auto
Dialogue: 0,1:30:26.61,1:30:30.58,Default,,0,0,0,,这样结果打印出来也是一样的
Dialogue: 0,1:30:31.52,1:30:43.37,Default,,0,0,0,,然后就是之前这样一个个去get ,还是很就可以用新好像十七新颖论证了结构化绑定一
Dialogue: 0,1:30:44.38,1:31:01.27,Default,,0,0,0,,首先就是oppo ,然后一个方括号里面写每个的那个字段名,然后你就可以用c out 去打印出来的零号元素,一号元素、二号元素就很方便
Dialogue: 0,1:31:02.41,1:31:10.19,Default,,0,0,0,,0 5.8块这个就和拍摄的那个解包有点像
Dialogue: 0,1:31:10.65,1:31:15.89,Default,,0,0,0,,然后这个结构化绑定它也可以绑定为引用
Dialogue: 0,1:31:15.89,1:31:23.17,Default,,0,0,0,,就比如如果突破是一个引用,那这里也能绑定一个引用这种
Dialogue: 0,1:31:23.17,1:31:49.98,Default,,0,0,0,,总之呃就是如果你电厂突破了0 ,首先是一开始为三嘛,然后你写入个算式,因为算式是个引用它和突破的那个冲泡的那个山是同一个地址,所以你写入的份上你会改变突破的零号变量,然后他也可以绑定为万能推导
Dialogue: 0,1:31:49.98,1:31:56.35,Default,,0,0,0,,然后由于历史原因,万能推导必须用两个核才能绑定
Dialogue: 0,1:31:56.35,1:32:03.02,Default,,0,0,0,,这样也是因为two pos 一样嘛,这里也会绑定为绑定为引用
Dialogue: 0,1:32:03.02,1:32:11.96,Default,,0,0,0,,它呃然后其实你不要以为这个东西只能用于出口,它可以用于任何自定义内
Dialogue: 0,1:32:11.96,1:32:17.07,Default,,0,0,0,,就比如我有一个my class ,然后也可以用这个来解包
Dialogue: 0,1:32:17.07,1:32:37.23,Default,,0,0,0,,只要你保证这个这个括号里的数量和它是一样就可以了,就不能嵌套,都能嵌套所有的标准库里容器都用欠条,嗯,然后这样就变成括号
Dialogue: 0,1:32:37.23,1:33:02.16,Default,,0,0,0,,总之就是是不是很方便上一期说的构造函数可以用这个来初始化,然后现在结构也能支持任意自定义内容,但是gun 肯定不支持,因为gun 是针对two point ,然后drupal 它还可以用于有多个返回值的函数,什么意思呢?
Dialogue: 0,1:33:02.16,1:33:06.65,Default,,0,0,0,,就是有的函数它是有一个失败特征性
Dialogue: 0,1:33:06.65,1:33:14.51,Default,,0,0,0,,就比如开根号,如果这个X小于零的话,那开根号就失败了,就大于0
Dialogue: 0,1:33:14.51,1:33:21.25,Default,,0,0,0,,我返回真,然后开根号,如果失败的话,我就直接返回0.0
Dialogue: 0,1:33:21.25,1:33:30.97,Default,,0,0,0,,然后说boss 这里外面调用者也用了结构化保证它的是否成功嗯,成功才去打印
Dialogue: 0,1:33:30.97,1:33:40.87,Default,,0,0,0,,然后这个还有一个不足啊,用我虽然失败了,我还是得给他一个默认值,就很烦
Dialogue: 0,1:33:40.87,1:33:45.55,Default,,0,0,0,,所以说这时候就可以用option 了,它更方便了
Dialogue: 0,1:33:45.55,1:33:49.98,Default,,0,0,0,,它只需要在成功的时候直接返回这个字
Dialogue: 0,1:33:50.31,1:33:56.79,Default,,0,0,0,,然后如果失败,那就返回no OPT它会变成一个失败的状态
Dialogue: 0,1:33:56.79,1:34:06.90,Default,,0,0,0,,然后返回的时候用f net 拍淄博领,判断是否为no OPT如果为no OPT的话,就会返回找不到
Dialogue: 0,1:34:06.90,1:34:19.68,Default,,0,0,0,,如果找到的话,你就可以继续用rate 0volume获取刚才得到的这个嗯,然后它还有一个很方便
Dialogue: 0,1:34:19.68,1:34:25.25,Default,,0,0,0,,就是如果你只想写一行,你可以用late 点volume home
Dialogue: 0,1:34:25.25,1:34:34.92,Default,,0,0,0,,就是代表如果volume 如果没有volume 的话,也就是如果has volume ,那就继续给他的volume
Dialogue: 0,1:34:34.92,1:34:41.95,Default,,0,0,0,,如果没有的话,他就会返回3 ,这是一个很方便的帮手函数
Dialogue: 0,1:34:42.37,1:34:50.03,Default,,0,0,0,,然后open 性还有一个特点就是它的这个点warning 会检测是否为空
Dialogue: 0,1:34:50.03,1:35:05.23,Default,,0,0,0,,如果你没有判断是否为空,而就是如果net 为nova OPT,你就直接去点warning,它会报错,说你错误的option 访问很小吗?
Dialogue: 0,1:35:05.23,1:35:24.94,Default,,0,0,0,,声音喂,然后opportunity 呢没有任务是会检测空的,而option 也就是解引用指针的这个语法,它是不会简称的,但是它有效率上的优势,而且写起来更加简便
Dialogue: 0,1:35:24.94,1:35:32.51,Default,,0,0,0,,然后如果你的official 是个结构体,这个用这个箭头来访问也是可以的
Dialogue: 0,1:35:32.51,1:35:37.65,Default,,0,0,0,,当然你得保证里面有值,再去用这个乘符号
Dialogue: 0,1:35:37.98,1:35:50.71,Default,,0,0,0,,然后还有一个呢就是它支持open the book,就是能隐私的自动转换为不谁用的F它可以直接把health volume 去掉,填写成f that
Dialogue: 0,1:35:51.04,1:35:58.83,Default,,0,0,0,,所以opportunity 呢它有点像访问,有点像在模仿这个指针
Dialogue: 0,1:35:59.16,1:36:08.95,Default,,0,0,0,,i know OPT就代表no point 的意思,而且它比指针更安全,因为它是符合RNI思想
Dialogue: 0,1:36:08.95,1:36:24.87,Default,,0,0,0,,就是如果我这里写的SQRT,我不需要另一个float,而且它是分配在栈上的,而不是追上它的效率就更高,已经最大了吗?
Dialogue: 0,1:36:30.67,1:36:41.36,Default,,0,0,0,,然后然后就是这个刚才说opportunity 呢是一个更安全的指针,那么它就是一个更安全的union 了
Dialogue: 0,1:36:41.78,1:36:53.77,Default,,0,0,0,,就是有时候我们需要存储一个对象,它可以存it 也可以存float ,它是会选取其中一个的,而不是全部成
Dialogue: 0,1:36:53.77,1:36:56.63,Default,,0,0,0,,如果全部呈,那就用触碰
Dialogue: 0,1:36:56.63,1:37:02.91,Default,,0,0,0,,如果只成一个的话,就可以用very end very end 它比union 更安全
Dialogue: 0,1:37:02.91,1:37:18.06,Default,,0,0,0,,因为它符合IIS思想,然后给YYY的赋值也更方便,只需要用一个等号,它会自动根据右边的类型来决定要放到哪一个容器
Dialogue: 0,1:37:18.39,1:37:23.42,Default,,0,0,0,,它和resident 的island 是一样的
Dialogue: 0,1:37:23.42,1:37:43.13,Default,,0,0,0,,然后option 呢strength the opening 了,嗯,然后visit 要获取呢也是用STEget STEget 可以获取它就在间括号里写一个in 它就代表获取它为in 的那个容器的
Dialogue: 0,1:37:43.48,1:37:50.99,Default,,0,0,0,,当然也可以写SCget 0 ,这样的话呢就和那个int 是等价的
Dialogue: 0,1:37:50.99,1:37:57.26,Default,,0,0,0,,但它就以你预先store 是这个violent 列表第几个类型
Dialogue: 0,1:37:57.63,1:38:13.58,Default,,0,0,0,,然后get 顺便一提呢,就是如果你目前存的是一个古典类型,而你却调用了get it 它就会出错
Dialogue: 0,1:38:13.91,1:38:25.17,Default,,0,0,0,,所以如果我想要判断是不是为inter 怎么办,用SNTDholds alternative 就可以
Dialogue: 0,1:38:25.17,1:38:40.57,Default,,0,0,0,,如果它它里面的这个类型是这个函数就会返回,所以就可以用这个来进行多个判断,就可以打印一个variant 里的字
Dialogue: 0,1:38:40.90,1:38:47.92,Default,,0,0,0,,不管是in 还是front ,可以看到这里有两个他们都会被正确打印
Dialogue: 0,1:38:49.35,1:39:08.70,Default,,0,0,0,,然后如果你知道very entire ,你真的这个索引号是多少,也可以用V点index ,然后就可以无视这个类型的名字,直接用01去判断嗯,怎么样
Dialogue: 0,1:39:11.58,1:39:27.55,Default,,0,0,0,,对呀,我知道no point 不是no ,这个不是等于等于老哥,他是两个不同的类型的,他只是行为上很像,但他不一样,他不一样
Dialogue: 0,1:39:27.55,1:39:34.59,Default,,0,0,0,,他模仿指针就是为了让C语言的人能够快速适应 C++
Dialogue: 0,1:39:35.09,1:39:43.80,Default,,0,0,0,,对呀,no point , 它只是有一个隐式的转换,它能够隐式转换成任何一个指针
Dialogue: 0,1:39:44.22,1:40:05.84,Default,,0,0,0,,然后no panel 它其实不是一个嗯就是他no point 的类型,其实就是你可以看一下s point 杠一这个东西是会返回boss 的
Dialogue: 0,1:40:09.59,1:40:14.44,Default,,0,0,0,,如果我没记错的话,它是会返回boss 的,对吧?
Dialogue: 0,1:40:14.44,1:40:19.87,Default,,0,0,0,,所以no point 不是一个紧张,而是一个特殊的类型
Dialogue: 0,1:40:20.49,1:40:31.33,Default,,0,0,0,,但是它又能够自动转换为任何他能够转换为任何指针
Dialogue: 0,1:40:33.27,1:40:37.16,Default,,0,0,0,,总之它能够转换为任何的
Dialogue: 0,1:40:37.16,1:40:57.15,Default,,0,0,0,,然后诺OPTOOPT它又是一个特殊的类型,它的类型是no OPT杠7就是C超里面有很多这种有很多这种它的定义大概是这样的,它里面啥也没定义
Dialogue: 0,1:40:57.15,1:41:04.47,Default,,0,0,0,,它的唯一功能就是就是作为一个构造函数的重载,知道吗?
Dialogue: 0,1:41:05.34,1:41:16.45,Default,,0,0,0,,它的唯一功能就是作为构造函数的一个重载,然后就是这它大概是长这样,他大概是长这样子的吗?
Dialogue: 0,1:41:16.45,1:41:25.14,Default,,0,0,0,,它唯一的功能就是作为一个重载,能够把它初始化为空,而不是因为它真的是一个什么诺基
Dialogue: 0,1:41:25.47,1:41:29.61,Default,,0,0,0,,它唯一的价值就是它这个类型与众不同
Dialogue: 0,1:41:31.34,1:41:49.84,Default,,0,0,0,,你可以去查查这个可以去查查这个这个也是这种思想下的场,他不是一个他不是说这个类型你要存储什么,而只是用他的一个名字,知道吧?
Dialogue: 0,1:41:49.84,1:41:52.93,Default,,0,0,0,,就是利用重载的这种特性
Dialogue: 0,1:41:56.33,1:42:03.43,Default,,0,0,0,,然后刚才说这样得一个个去f else 去判断索引和类型
Dialogue: 0,1:42:03.43,1:42:17.98,Default,,0,0,0,,但是可以用批量批,就是嗯就是你如果这里有一个variant inter float 呢,然后我调用的第一个参数就就是一个lambda
Dialogue: 0,1:42:17.98,1:42:23.78,Default,,0,0,0,,然后lambda 的女生就是它的参数是一个模板类型
Dialogue: 0,1:42:24.33,1:42:26.88,Default,,0,0,0,,消失
Dialogue: 0,1:42:26.88,1:42:38.74,Default,,0,0,0,,比如这里auto cast t 那这个auto 它就会自动自动把它编译器会自动把它针对inter 和针对flow 的策划
Dialogue: 0,1:42:38.74,1:42:48.77,Default,,0,0,0,,就是它会调用一遍inter ,然后也会调用一遍float 它和我们刚刚这样的是等价的
Dialogue: 0,1:42:48.77,1:43:00.27,Default,,0,0,0,,没办法了,这就是应用到了刚刚所在auto 的lambda ,它是模板函数,它会惰性,也会多次编译
Dialogue: 0,1:43:00.27,1:43:11.49,Default,,0,0,0,,所以这个代码其实是被编译了两遍,从而实现了刚才需要分才能实现的效果,明白吧?
Dialogue: 0,1:43:15.48,1:43:20.33,Default,,0,0,0,,然后然后这个very end 它这种模式叫静态观看
Dialogue: 0,1:43:20.33,1:43:29.78,Default,,0,0,0,,现在很多面向对象语言都是动态波态,比如虚函数和抽象类的继承,就属于动态波态
Dialogue: 0,1:43:29.78,1:43:34.91,Default,,0,0,0,,动态波态可以构建一个数啊静态多态就不行
Dialogue: 0,1:43:34.91,1:43:45.98,Default,,0,0,0,,但静态多态的优点是它的性能开销小,而且它可以利用这个重载特这个量不大,具有多次变异特点
Dialogue: 0,1:43:45.98,1:43:51.92,Default,,0,0,0,,你就只需要写一遍这个C2 ,而不需要每个分支都行
Dialogue: 0,1:43:52.82,1:43:59.80,Default,,0,0,0,,它很好的利用了存在代码一致,而实际边一不一致的效果
Dialogue: 0,1:44:00.13,1:44:05.86,Default,,0,0,0,,明白了吧,听得清吗?
Dialogue: 0,1:44:06.65,1:44:20.82,Default,,0,0,0,,我猜有的人说我太太轻了,就是网上不是有一个梗嘛,就是说什么什么什么,就像四大红柱
Dialogue: 0,1:44:20.82,1:44:30.48,Default,,0,0,0,,不呃不是不是看四大名著,不看红楼梦,然后就这种人,他内部什么什么不能理解什么什么
Dialogue: 0,1:44:30.48,1:44:36.66,Default,,0,0,0,,那我觉得visit 和visit 就是这种关系是不是挺好玩的
Dialogue: 0,1:44:38.87,1:44:46.48,Default,,0,0,0,,然后STTviolent 除了刚刚能够visit 单个baby ,and 它还可以visit 多个
Dialogue: 0,1:44:46.48,1:45:01.17,Default,,0,0,0,,就比如我这里直线一个end ,它可以把两个加起来,他就是首先它会先把先去罗列一个int 加int 的情况
Dialogue: 0,1:45:01.17,1:45:12.89,Default,,0,0,0,,然后它在罗内int 加flow 的情,再来判断是不是blood 加int 的,然后再来判断是不是floor 加floor 的
Dialogue: 0,1:45:13.22,1:45:22.14,Default,,0,0,0,,就是说这个函数是被实例化的四点,它这个模板的每一个排列它都被撕了一遍
Dialogue: 0,1:45:23.74,1:45:28.75,Default,,0,0,0,,对呀,就是这个音量可以调的
Dialogue: 0,1:45:30.25,1:45:39.91,Default,,0,0,0,,所以如果你有两个参数,还有element ,有N个类型,那就是N平方次,这可能会导致变异变慢
Dialogue: 0,1:45:39.91,1:45:46.08,Default,,0,0,0,,但是呢但是呢标准库会保证这个调用是OE的
Dialogue: 0,1:45:46.08,1:45:54.23,Default,,0,0,0,,也就是说它是通过一个jump 指令,它非常高效,它不会去用FL认证
Dialogue: 0,1:45:56.72,1:46:03.82,Default,,0,0,0,,所以说这个相比不但写起来简洁,而且还有性能优势
Dialogue: 0,1:46:05.15,1:46:15.90,Default,,0,0,0,,然后还有一个就是very ,and 他可以有返这个visit ,它的里面的函数可以是返回值
Dialogue: 0,1:46:15.90,1:46:20.60,Default,,0,0,0,,就这里我们不是先预先说明一个返回值吗?
Dialogue: 0,1:46:21.58,1:46:25.90,Default,,0,0,0,,这样就相当于初始化了一遍,又复制了一遍
Dialogue: 0,1:46:25.90,1:46:30.94,Default,,0,0,0,,根据上一课学的最好把它初始化的时候就为拷贝
Dialogue: 0,1:46:30.94,1:46:37.50,Default,,0,0,0,,所以说我们可以把它作为返回值,这样就不需要先初始化一遍
Dialogue: 0,1:46:37.50,1:46:40.13,Default,,0,0,0,,然后这时候我们得用两个
Dialogue: 0,1:46:40.55,1:46:54.15,Default,,0,0,0,,当然因为这时候每一个的返回不一样,我们得指定这个量不大,返回为very end ,不然的话visit 就不知道返回啥了
Dialogue: 0,1:46:57.61,1:46:58.76,Default,,0,0,0,,明白吧?
Dialogue: 0,1:46:58.76,1:47:05.42,Default,,0,0,0,,然后这还是我们刚刚这个3加3.14等于6.14
Dialogue: 0,1:47:06.36,1:47:09.84,Default,,0,0,0,,感谢你的观看,这就讲完了
Dialogue: 0,1:47:09.84,1:47:21.25,Default,,0,0,0,,然后就是我们这个作业,我还在就是这个链接,暂时还是此链接,就待会儿我会把作业传上去
Dialogue: 0,1:47:21.88,1:47:26.49,Default,,0,0,0,,还有问题吗?