c++ - 模板库中的名称查找:我们为什么要添加这个->
问题描述
考虑以下:
struct Base {
void foo();
};
template <class T>
struct Derived : Base {
void bar() {
this->foo();
}
};
通常,我们解释它this->
产生foo()
一个依赖名称,因此它的查找被推迟到第二阶段,即模板实例化点。
但是第二阶段查找只调用不考虑成员函数的 ADL,不是吗?
我将不胜感激任何指向解释上述代码编译原因的标准段落的指针。
解决方案
但是第二阶段查找只调用不考虑成员函数的 ADL,不是吗?
它不是。然而,ADL 添加到查找集中,它并不包含所有这些。此外,您在此处解释的想法适用于 中的后缀表达式postfix-expression(args)
,当后缀表达式是unqualified-id时。
[温度.dep]
1 ... 在以下形式的表达式中:
后缀表达式(表达式列表选择)如果后缀表达式是一个非限定 ID,则非限定 ID 表示一个从属名称,如果
- [...具体条件...]
如果运算符的操作数是依赖于类型的表达式,则该运算符也表示依赖名称。此类名称是未绑定的,并且在模板定义的上下文和实例化点的上下文中都在模板实例化点 ([temp.point]) 处查找。
因此,如果您在那里foo()
,则查找将不考虑成员,而是仅在定义和实例化点尝试自由函数(假设我们有一个从属表达式,ADL 可以添加到查找集)。
但是对于this->foo
(我故意省略了调用,以讨论后缀表达式),我们拥有类成员访问权限。此处适用其他段落:
[温度.dep.type]
5名称是当前实例化的成员,如果它是
- [...]
- id-expression 表示类成员访问表达式中的成员,其对象表达式的类型是当前实例化,并且 id-expression 在查找时引用作为当前实例化的类的至少一个成员或其非依赖基类。[ 注意:如果没有找到这样的成员,并且当前实例化有任何依赖的基类,那么 id-expression 是未知特化的成员;见下文。——尾注]
6一个名字是一个未知专业的成员,如果它是
- [...]
- 一个 id 表达式,表示类成员访问表达式中的成员,其中任一
- 对象表达式的类型是当前实例化,当前实例化至少有一个依赖基类,id-expression 的名称查找未找到当前实例化或非依赖基类的类的成员其中;或者
7类似地,如果对象表达式的类型是当前实例化的类成员访问表达式中的 id 表达式不引用当前实例化的成员或未知特化的成员,则程序是非良构的即使包含成员访问表达式的模板没有被实例化;无需诊断。
这些项目符号告诉我们this->foo
遇到时要执行的查找。它只查找成员。在我们的例子中,我们在当前实例化中有一个不依赖的基类,因此可以明确地找到该成员。
找到成员函数后,后缀表达式this->foo
表示可调用,这就是函数调用的解析方式。
推荐阅读
- python - 熊猫在函数内编辑数据框而不返回数据框对象
- javascript - 无法获取构造函数(value1,value2){ this.value1 = value1 this.value2 = value2 }
- ios - 从 ios wkwebview 上传时是否可以设置图像数量限制?
- c# - 在 Heroku 上为只监听 https 的服务使用哪个环境变量
- excel - Excel:将鼠标悬停在 Excel 图像链接上的预览 - 跟进
- php - 如何将复选框数据插入数据库codeigniter框架
- rust - 期货 - 预期的(),找到结构期货::地图
- next.js - 在 Next 中导入样式会在基本使用示例之后引发错误
- azure - 如何更改在 Azure Databricks 中运行的 Spark 用户作业?
- azure-logic-apps - 基于元素索引过滤数组的有效方法