Skip to content

Commit

Permalink
修改错别字与标点
Browse files Browse the repository at this point in the history
  • Loading branch information
Mq-b committed Mar 22, 2024
1 parent a7e6b14 commit f81964b
Show file tree
Hide file tree
Showing 8 changed files with 13 additions and 13 deletions.
2 changes: 1 addition & 1 deletion code/04显式实例化解决模板分文件问题/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ int main() {
x3.f();
x3.f2();

// 类模板分文件 我们写了两个类模板 X X2,他们一个使用了成员函数显式实例化,一个类模板显式实例化,进行对比
// 类模板分文件 我们写了两个类模板 X X2,它们一个使用了成员函数显式实例化,一个类模板显式实例化,进行对比
// 这主要在于我们所谓的类模板分文件,其实类模板定义还是在头文件中,只不过成员函数定义在 cpp 罢了。
}
10 changes: 5 additions & 5 deletions md/第一部分-基础知识/01函数模板.md
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ auto max(const T& a, const T2& b) -> decltype(true ? a : b){

这是 C++11 后置返回类型,它和我们之前用默认模板实参 `RT` 的区别只是稍微好看了一点吗?

不,**他们的返回类型是不一样的**,如果函数模板的形参是**类型相同** `true ? a : b` 表达式的类型是 **`const T&`**;如果是 `max(1, 2)` 调用,那么也就是 `const int&`;而前面的例子只是 `T``int`(前面都是用模板类型参数直接构造临时对象,而不是有实际对象,自然如此,比如 `T{}`)。
不,**它们的返回类型是不一样的**,如果函数模板的形参是**类型相同** `true ? a : b` 表达式的类型是 **`const T&`**;如果是 `max(1, 2)` 调用,那么也就是 `const int&`;而前面的例子只是 `T``int`(前面都是用模板类型参数直接构造临时对象,而不是有实际对象,自然如此,比如 `T{}`)。

> 假设以 `max(1,1.0)` 调用,那么自然返回类型不是 `const T&`
>
Expand All @@ -327,9 +327,9 @@ decltype(auto) max(const auto& a, const auto& b) {
1. [返回类型推导](https://zh.cppreference.com/w/cpp/language/function#.E8.BF.94.E5.9B.9E.E7.B1.BB.E5.9E.8B.E6.8E.A8.E5.AF.BC)(也就是函数可以直接写 auto 或 decltype(auto) 做返回类型,而不是像 C++11 那样,只是后置返回类型。
2. [`decltype(auto)`](https://zh.cppreference.com/w/cpp/language/auto)*如果返回类型没有使用 decltype(auto),那么推导遵循[模板实参推导](https://zh.cppreference.com/w/cpp/language/template_argument_deduction#.E5.85.B6.E4.BB.96.E8.AF.AD.E5.A2.83)的规则进行*我们上面的 `max` 示例如果不使用 decltype(auto),按照模板实参的推导规则,是不会有引用和 cv 限定的,就只能推导出返回 `T` 类型。
2. [`decltype(auto)`](https://zh.cppreference.com/w/cpp/language/auto)*如果返回类型没有使用 decltype(auto),那么推导遵循[模板实参推导](https://zh.cppreference.com/w/cpp/language/template_argument_deduction#.E5.85.B6.E4.BB.96.E8.AF.AD.E5.A2.83)的规则进行*我们上面的 `max` 示例如果不使用 decltype(auto),按照模板实参的推导规则,是不会有引用和 cv 限定的,就只能推导出返回 `T` 类型。
> 大家需要注意后置返回类型和返回类型推导的区别,他们不是一种东西,后置返回类型虽然也是写的 `auto` ,但是它根本没推导,只是占位。
> 大家需要注意后置返回类型和返回类型推导的区别,它们不是一种东西,后置返回类型虽然也是写的 `auto` ,但是它根本没推导,只是占位。
模板的默认实参无处不在,比如标准库的 [std::vector](https://zh.cppreference.com/w/cpp/container/vector)[std::string](https://zh.cppreference.com/w/cpp/string/basic_string),当然了,这些都是类模板,我们以后会讲到。
Expand Down Expand Up @@ -406,7 +406,7 @@ void sum(Args...args){}
模板中需要 typename 后跟三个点 Args,函数形参中需要用模板类型形参包后跟着三个点 再 args。
**args 是函数形参包,Args 是类型形参包,他们的名字我们可以自定义**
**args 是函数形参包,Args 是类型形参包,它们的名字我们可以自定义**
**args 里,就存储了我们传入的全部的参数,Args 中存储了我们传入的全部参数的类型。**
Expand Down Expand Up @@ -435,7 +435,7 @@ sum 的 `Args...args` 被展开为 `const char * args0, int args1, double args2`
`&args...` 中 `&args` 就是模式,在展开的时候,模式,也就是省略号前面的一整个表达式,会被不停的填入对象并添加 `&`,然后逗号分隔。直至形参包的元素被消耗完。
那么根据这个,我们就能写出一些有意思的东西,比如一次性把他们打印出来
那么根据这个,我们就能写出一些有意思的东西,比如一次性把它们打印出来
```cpp
template<typename...Args>
Expand Down
2 changes: 1 addition & 1 deletion md/第一部分-基础知识/04模板全特化.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ int main(){
我们使用全特化,实现了一个 `is_void` 判断模板类型实参是不是 `void` 类型。
虽然很简单,但我们还是稍微强调一下:同一个类模板实例化的不同的类,彼此之间毫无关系,而静态数据成员是属于类的,而不是模板类;模板类实例化的不同的类,他们的静态数据成员不是同一个,请注意。
虽然很简单,但我们还是稍微强调一下:同一个类模板实例化的不同的类,彼此之间毫无关系,而静态数据成员是属于类的,而不是模板类;模板类实例化的不同的类,它们的静态数据成员不是同一个,请注意。
---
Expand Down
2 changes: 1 addition & 1 deletion md/第一部分-基础知识/05模板偏特化.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

模板偏特化这个语法让**模板实参具有一些相同特征**可以自定义,而不是像全特化那样,必须是**具体的**什么类型,什么值。

比如:指针类型,这是一类类型,有 `int*``double*``char*`,以及自定义类型的指针等等,他们都属于指针这一类类型;可以使用偏特化对指针这一类类型进行定制。
比如:指针类型,这是一类类型,有 `int*``double*``char*`,以及自定义类型的指针等等,它们都属于指针这一类类型;可以使用偏特化对指针这一类类型进行定制。

- ***模板偏特化使我们可以对具有相同的一类特征的类模板、变量模板进行定制行为。***

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ int main() {
x3.f();
x3.f2();

// 类模板分文件 我们写了两个类模板 X X2,他们一个使用了成员函数显式实例化,一个类模板显式实例化,进行对比
// 类模板分文件 我们写了两个类模板 X X2,它们一个使用了成员函数显式实例化,一个类模板显式实例化,进行对比
// 这主要在于我们所谓的类模板分文件,其实类模板定义还是在头文件中,只不过成员函数定义在 cpp 罢了。
}
```
Expand Down
2 changes: 1 addition & 1 deletion md/第一部分-基础知识/08折叠表达式.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ int main(){
}
```
这个示例很好,那么简单总结一下:左折叠和右折叠是需要注意的,他们的效果可能不同
这个示例很好,那么简单总结一下:左折叠和右折叠是需要注意的,它们的效果可能不同
其实按照以上示例效果 `(4-(5-6))` `((4-5)-6)` 还可以总结一段简单的话:***右折叠就是先算右边,左折叠就是先算左边***
Expand Down
2 changes: 1 addition & 1 deletion md/第一部分-基础知识/10了解与利用SFINAE.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ int main(){
以上的示例很好的向我们展示了 SFINAE 的作用,可以影响重载决议。
`foo<B<C>>(1)`、`foo<void>(1)` 如果根据一般直觉,他们都会选择到 `void foo(int)`,然而实际却不是如此;
`foo<B<C>>(1)`、`foo<void>(1)` 如果根据一般直觉,它们都会选择到 `void foo(int)`,然而实际却不是如此;
这是因为 `foo<void>(1);` 去尝试匹配 `void foo(int)` 的时候,模板实参类型 `void` 进行替换,就会变成:
Expand Down
4 changes: 2 additions & 2 deletions md/第一部分-基础知识/11约束与概念.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ void f(T){}

## 约束

前面我们讲的都是非常基础的*概念*(concept)使用,他们的约束也都十分简单,本节我们详细讲一下。
前面我们讲的都是非常基础的*概念*(concept)使用,它们的约束也都十分简单,本节我们详细讲一下。

约束是逻辑操作和操作数的序列,它指定了对模板实参的要求。它们可以在 requires 表达式(见下文)中出现,也可以直接作为概念的主体。

Expand Down Expand Up @@ -582,7 +582,7 @@ int main() {
- `requires` 表达式
如果你耐心看完,我相信也能意识到他们是互相掺杂,一起使用的。语法上虽然感觉有些多,但是也都很合理,我们只需要 ***带入***,按照基本的常识判断这是不是符合语法,基本上就可以了。
如果你耐心看完,我相信也能意识到它们是互相掺杂,一起使用的。语法上虽然感觉有些多,但是也都很合理,我们只需要 ***带入***,按照基本的常识判断这是不是符合语法,基本上就可以了。
`requires` 关键字的用法很多,但是划分的话其实就两类
Expand Down

0 comments on commit f81964b

Please sign in to comment.