首页 > 解决方案 > 参数相关查找如何在搜索点之后找到声明?

问题描述

struct A {
    void g(A a) {
        f(a);
        }
    friend void f(A a);
    };
void f(A a) { }
int main() {
    A a;
    a.g(a);
}  

上面的代码编译并运行没有问题,但我不知道查找是如何f(a)发生的。最初将在类及其父作用域(即全局作用域)中发生非限定名称查找。由于friend f不是成员并且没有using-directive我认为不合格的名称查找将一无所获。因此发生了依赖于参数的查找。C++ 草案 2021(N4901)(第 6.5.4 章 [basic.lookup.argdep] )引用:

依赖于参数的查找查找所有函数和函数模板的声明(4.1)——通过搜索任何关联的命名空间,或(4.2)——被声明为任何类的友元(11.8.4),在关联实体集或 (4.3) — 已导出,附加到命名模块 M (10.2),不出现在包含查找点的翻译单元中,并且具有相同的最内层非内联命名空间范围作为附加到 M (6.6) 的关联实体的声明。

朋友声明看起来适合 4.2,但是全局范围void f(A a){}呢?它看起来不适合 4.1(因为它不先于搜索点),既不适合 4.2 也不适合 4.3。如何找到定义函数?

标签: c++lookupargument-dependent-lookup

解决方案


[basic.scope.class]/1在类中声明的名称的潜在范围不仅包括名称声明点之后的声明区域,还包括该类中的所有函数体......。

因此,f由声明引入的名称friend在 的主体中可见g,并且可以通过非限定查找找到。


推荐阅读