C++名称解析(以及重载)规则列表

43

我在哪里可以找到C++兼容编译器必须应用的规则列表,以执行名称解析(包括重载)?

我想要一个类似自然语言算法或流程图的东西。

C++标准当然有这套规则,但随着引入新的语言语句,结果很难记住。

长话短说,我想知道"编译器在看到名称'A'时会做什么"的完整详细答案。

我知道C++都是"如果X我们就这样做,但如果Z成立就不会Y",因此,我想知道是否可能使其更线性。

编辑:我正在起草这个主题的草稿,一旦发布,可以集体改进。但是我最近非常忙,可能需要时间才能有可发布的东西。如果有人感兴趣,我将把"原始txt文件上的个人笔记"提升为更好的东西并发布它。


7
《C++ Templates - The Complete Guide》的附录B介绍了函数重载决议。"在本附录中,我们提供了对函数重载决议规则的相当详细的概述。但由于这个过程的复杂性,我们并不保证涵盖该主题的每个部分。" - Karoly Horvath
5
标准中的规则分散且相互关联性非常高,贯穿整个文档。 - Lightness Races in Orbit
9
我打算在这个问题上添加赏金,只要它变得可用,我希望有一个比标准更易读的严肃名称查找和重载解析规则的参考。 - Matteo Italia
我想指出这个过程分为两个不同的阶段。1.名称查找/2.重载解析。由于问题已经很广泛,我觉得如果将其分成两个部分会更具有决定性。它们是独立应用的,我认为重载解析仅发生在查找到的名称集上。 - Matthieu M.
@Matthieu M. 这是真的。重载作用于名称解析的结果(尽管名称查找在找到可能的多个名称的第一个名称所在的范围结束)。但是我的意图是拥有一个包含两者的单个(大)数字。 - user781847
@knm241:因为它们彼此之间不会产生影响,所以我认为如果你将问题拆分开来,你会有更好的机会得到答案。这甚至可能值得成为一个 C++-faq,但应该先在休息室里提问。 - Matthieu M.
1个回答

12

总的来说:

  • 如果名称以::开头,例如 ::AX::A,则使用限定名查找。首先查找X(如果不存在则使用全局命名空间),然后在其中查找A。如果X是一个类,并且A不是直接成员,则在X的所有直接基类中查找。如果A在多个基类中被找到,则失败。

  • 否则,如果名称用作函数调用,例如A(X),则使用参数相关查找。这是难点。在X类型声明的命名空间中查找A,在X的友元中查找以及如果X是模板实例化,则对涉及的所有参数同样进行查找。仅由typedef关联的作用域不适用。同时进行非限定名查找。

  • 如果参数相关查找不适用,则从非限定名查找开始。这是通常变量被找到的方式。从当前范围开始向外工作,直到找到名称。请注意,这尊重using namespace指令,而其他两种情况则不是。

简单地查看标准文件将揭示许多例外和陷阱。例如,在使用参数相关查找生成潜在重载列表之前,非限定查找用于确定名称是否用作函数调用,而不是用作强制表达式。非限定查找不会在嵌套或本地类的封闭作用域中查找对象,因为这样的对象可能在引用时不存在。

运用常识,并在直觉失败时提出更具体的问题。


唉,这远非整个论点的完整画面。请注意:你写的“然后在A的所有直接基础中查找”,你是指“然后在A的所有基础中查找”吗? - user781847
@knm:我的意思是,从A的直接基类开始,然后对于每个基类,递归到它的基类。如果这个搜索的任何两个分支都找到了X,则该过程失败。 - Potatoswatter
@knm241: 已修复,X是被搜索的类(作用域),而A则是被搜索的元素。 - Matthieu M.
类X的基类的基类是X的间接基类。根据标准 :) 再次感谢您花时间回答这个问题。 - user781847

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接