在命名空间内的类的友元函数

Ale*_*Dan 6 c++ namespaces friend

关于这个代码,我有两个问题:

namespace A { class window; }

void f(A::window);

namespace A
{
    class window
    {
    private:
       int a;
       friend void ::f(window);
    };
}

void f(A::window rhs)
{
    std::cout << rhs.a << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

1)为什么我需要通过执行:: f(window)来限定窗口类中的成员函数f是全局的?

2)为什么我需要在这种特殊情况下预先声明函数f(A :: window),而当在类名称空间内没有定义类时,可以在函数声明为朋友之后声明函数.

Cap*_*ous 4

当您声明f()为友元时A,如果尚不存在前向声明,则实际上是在包含类(在本例中)的封闭命名空间中完成的。

所以这...

namespace A
{
    class window
    {
    private:
        friend void ::f(window);
    };
}
Run Code Online (Sandbox Code Playgroud)

本质上变成了这个……

namespace A
{
    class window;
    void f(window);

    class window
    {
    private:
        friend void f(window);
    };
}
Run Code Online (Sandbox Code Playgroud)

编辑:这是 C++ 标准中的一个片段,明确讨论了这种情况:

标准7.3.1.2/3:

命名空间中首先声明的每个名称都是该命名空间的成员。如果非局部类中的友元声明首先声明了一个类或函数,则该友元类或函数是最内层封闭命名空间的成员。在该命名空间范围内(在授予友谊的类定义之前或之后)提供匹配声明之前,非限定查找(3.4.1)或限定查找(3.4.3)都无法找到好友的名称。