Skip to content

Commit

Permalink
更新第九题标准答案
Browse files Browse the repository at this point in the history
  • Loading branch information
Mq-b committed Aug 17, 2023
1 parent 95a88a7 commit 2a8ed5c
Showing 1 changed file with 36 additions and 0 deletions.
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -775,3 +775,39 @@ int main() {
<br>
### 标准答案
根据我们的提示 **名字查找**,我看大家多少都还是能查到一些东西。我们慢慢说吧,首先名字查找分为:**有限定** 名字查找,**无限定** 名字查找。
<details>
<summary><h4>有限定名字查找指?</h4></summary>
出现在作用域解析操作符 `::` 右边的名字是限定名(参阅有限定的标识符)。 限定名可能代表的是:
类的成员(包括静态和非静态函数、类型和模板等)
命名空间的成员(包括其他的命名空间)
枚举项
如果 `::` 左边为空,那么查找过程只会考虑全局命名空间作用域中作出(或通过 using 声明引入到全局命名空间中)的声明。
</details>
<br>
```cpp
this->f();
```

那么显然,这个表达式并 **不是有限定名字查找**,那么我们就去[无限定名字查](https://zh.cppreference.com/w/cpp/language/unqualified_lookup)找中寻找答案。

我们找到**模板定义**
>对于在模板的定义中所使用的**非待决名**,当**检查该模板的定义时将进行无限定的名字查找**。在这个位置与声明之间的绑定并不会受到在实例化点可见的声明的影响。而对于在模板定义中所使用的**待决名**,**它的查找会推迟到得知它的模板实参之时**。此时,ADL 将同时在模板的定义语境和在模板的实例化语境中检查可见的具有外部连接的 (C++11 前)函数声明,而非 ADL 的查找只会检查在模板的定义语境中可见的具有外部连接的 (C++11 前)函数声明。(换句话说,在模板定义之后添加新的函数声明,除非通过 ADL 否则仍是不可见的。)如果在 ADL 查找所检查的命名空间中,在某个别的翻译单元中声明了一个具有外部连接的更好的匹配声明,或者如果当同样检查这些翻译单元时其查找会导致歧义,那么行为未定义。无论哪种情况,如果某个基类取决于某个模板形参,那么无限定名字查找不会检查它的作用域(在定义点和实例化点都不会)。

原文很长,但是看我们加粗的也足够了。如果你没有学习过[待决名](https://zh.cppreference.com/w/cpp/language/dependent_name),那这又会引入一个问题了。

我们这里简单描述一下吧:

`this->f()`是一个待决名,这个`this`依赖于模板`X`

所以,我们的问题可以解决了吗?

1. `this->f();` **是待决名**,所以它的查找会推迟到得知它模板实参之时(即知道父类是谁,可以访问父类)。
2. `f()` **是非待决名**,检查该模板的定义时将进行无限定的名字查找(不知道父类),按照正常的查看顺序,先类内(查找不到),然后全局(找到)。

0 comments on commit 2a8ed5c

Please sign in to comment.