Skip to content

Commit f03fb6f

Browse files
committed
Update public notes
1 parent 75e5768 commit f03fb6f

File tree

1 file changed

+73
-1
lines changed

1 file changed

+73
-1
lines changed

content/编程相关/编程语言/Cpp 之旅 第三版 读书笔记.md

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,4 +647,76 @@ template<typename Iter>
647647
Vector(Iter,Iter) -> Vector<typename Iter::value_type>
648648
```
649649
650-
*有点看不懂,我去补一下模板和泛型再回来看这本书。*
650+
*可以理解为手动指定当遇到特定类型的时候,使用什么模板参数。*
651+
652+
> **推导指引的效果往往很微妙,所以最好在模板类中通过设计来避免必须使用推导指引的情形。**
653+
654+
我也觉得很微妙。
655+
656+
此外喜欢名词和缩写词的,可以把「类模板参数推导」缩写成 CTAD。*我也不懂为什么作者要强调这个,可能作者不喜欢缩写词吧。*
657+
658+
### 参数化操作
659+
660+
要想表达将操作用类型或者值来参数化,有三种方法:
661+
- 模板函数
662+
- 函数对象:对象可以带数据,并以函数形式调用
663+
- 匿名函数表达式:函数对象的简略记法。
664+
665+
#### 模板函数
666+
667+
跟类模板差不多,就是模板化的函数。
668+
669+
#### 函数对象
670+
671+
用class来模拟函数,重载了operator()并且能携带数据,当然也可以用类模板的办法来参数化。
672+
673+
#### 匿名函数表达式
674+
675+
函数对象可以用来写明通用算法中的关键操作(比如Less_than对象与count()算法的关系),它有时也被叫作策略对象。
676+
677+
匿名函数表达式可以用 `[&](int a){ return a<s; }` 这样的语法来表达。
678+
679+
其中,`[&]` 是匿名函数的捕获列表,指定了函数体内所有局部变量可以以引用形式访问。如果要拷贝,可以以`[=]`以值方式捕获所有,以`[]`不捕获,以`[&x]`表示只以引用方式捕获`x`。以`[i,this]` 捕获多个对象。
680+
681+
匿名函数表达式当然也可以参数化。
682+
683+
```cpp
684+
template<class S>
685+
void rotate_and_draw(vector<S>& v, int r) {
686+
for_each(v, [](auto& s){ s->rotate(r); s->draw(); });
687+
}
688+
```
689+
690+
这里 auto 表示可以接受任意类型。
691+
692+
***需要注意的是,含有 auto 参数的匿名函数也是模板,也叫 泛型匿名函数。***
693+
694+
*我查了一下,函数参数用 auto 这个有点说法和历史的。C++11 不支持 auto。C++14/17 仅支持 lambda 表达式(也就是匿名函数)的 auto 参数,而到了 C++20 引入 **缩写函数模板** 语法糖后,才支持在非匿名函数中使用 auto 参数。C++20 里面在非匿名函数中使用 auto 会自动转换成模板函数。*
695+
696+
使用匿名函数,可以将任意语句变成表达式。
697+
698+
如果遇到了不含析构函数的对象(例如 C 代码),可以使用作用域终结函数(用匿名函数来实现的)来处理。
699+
700+
`[[nodiscard]] auto finally(F f)` 大概实现思路就是用一个类 `Final_action` 来包装原来不会析构的对象,而 `Final_action` 自身定义了析构函数,并且在析构函数中用 `free` 对包装的对象进行析构。(怎么感觉某种角度复刻了智能指针,只不过构造是用的匿名函数包装了类的构造)
701+
702+
`[[nodiscard]]` 属性修饰函数,确保用户不会忘记保存生成的返回值 `Final_action`.
703+
704+
代码如下:
705+
706+
```cpp
707+
template<class F>
708+
[[nodiscard]] auto finally(F f) {
709+
return Final_action{f};
710+
}
711+
712+
template<class F>
713+
struct Final_action {
714+
explict Final_action(F f): act(f) {}
715+
~Final_action() { act(); }
716+
F act;
717+
}
718+
719+
// 调用时
720+
finally([&]{free(p);}) // 离开作用域时自动调用匿名函数,使用 free 释放
721+
```
722+

0 commit comments

Comments
 (0)