对于朋友函数的依赖于参数的查找

Bar*_*rry 7 c++ friend-function language-lawyer argument-dependent-lookup

考虑以下:

namespace N {
    struct A { };

    struct B {
        B() { }
        B(A const&) { }
        friend void f(B const& ) { }
    };
}

int main() {
    f(N::B{}); // ok
    f(N::A{}); // error
}
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,案例成功 - 我们考虑相关的名称空间N::B和查找N::f(B const&).大.

第二种情况失败了.为什么?根据[namespace.memdef]:

如果friend非本地类中的声明首先声明了类,函数,类模板或函数模板,则该友元是最内层封闭命名空间的成员.[...]如果调用了友元函数或函数模板,则可以通过名称查找找到其名称,该名称查找考虑名称空间中的函数和与函数参数类型相关联的类(3.4.2).

的关联的命名空间N::AN,它的f一个成员,所以为什么不通过查找发现的?

Bri*_*ian 8

这是因为f没有在关联的类中声明.B当参数是type时B,是一个关联的类,但是当参数是type时,则不是A.

我引用[basic.lookup.argdep]/4,强调我的:

在考虑关联的命名空间时,查找与关联命名空间用作限定符时执行的查找相同(3.4.3.2),但以下情况除外:

- 忽略关联命名空间中的任何using-directive.

- 在关联类声明的任何命名空间范围的朋友函数或友元函数模板在其各自的命名空间中都是可见的,即使它们在普通查找期间不可见(11.3).

- 忽略除(可能重载)函数和函数模板之外的所有名称.