Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 命名空间内类的友元函数_C++_Namespaces_Friend - Fatal编程技术网

C++ 命名空间内类的友元函数

C++ 命名空间内类的友元函数,c++,namespaces,friend,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; } 名

关于下面的代码,我有两个问题:

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;
}
名称空间A{class window;}
空f(A::窗口);
名称空间A
{
类窗口
{
私人:
INTA;
friendvoid::f(窗口);
};
}
空f(A::窗口rhs)
{
std::cout当您将
f()
声明为好友时,如果转发声明尚未出现,则实际上是在包含类(
a
)的封闭命名空间中完成的

所以这个

namespace A
{
    class window
    {
    private:
        friend void ::f(window);
    };
}
本质上变成了这个

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

    class window
    {
    private:
        friend void f(window);
    };
}
<> > >编辑:这里是C++标准的一个片段,详细地解释了这个场景:

标准7.3.1.2/3:

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

对于1),您的函数不在名称空间中,因此必须使用::告诉编译器在名称空间之外搜索它

否则,它将只查找命名空间内的函数(这就是它们存在的原因)。Koenig查找在这里不适用,因为window类位于命名空间内

虽然不太确定2),但我打赌它与1相关。

1),因为函数
f
是在当前名称空间之外声明和定义的。如果您将类的定义移动到与函数相同的名称空间中,无论是全局的还是其他的,您都不需要这样做


2) 在引用函数之前,您始终需要声明函数。您的类使用friend语句引用函数。

这里有一个关于什么是友好类的快速解释@Hans抱歉,但这不在我的讨论范围之内question@Hans,请,请,不要链接cplusplus.com-你所说的引用是什么意思?当类不在内部时怎么办e任何NamaSpace都不是这种情况?它需要能够看到函数存在。如果类与函数定义位于同一命名空间中,则可能能够找到它,但声明顺序很重要。这也是为什么函数的定义必须位于类声明之后,因为它使用该类的成员。关于(2),参见CaptainObvlious的答案-有一个微妙的答案。Alexandan在这里不太正确。有时,朋友声明不需要引用以前声明的函数-相反,朋友声明本身算作函数的官方声明,函数可以在以后定义。参见CaptainObvlious的答案。因此,根据在上面的例子中,f(窗口)被视为命名空间a的成员?如果f(窗口)是在其自己的命名空间中定义的,比如命名空间B,会怎么样?f(窗口)会属于命名空间a和命名空间B吗?@VishnuPedireddi No,
f(窗口)
将在名称空间
A
B
中声明,但仅在
B
中实现。任何试图访问A::f(窗口)的尝试都将导致无法解决的链接器错误。@Vishnupediredidi:由您决定属于哪个链接器。如果您确实访问了f(窗口)在A内部,则它将属于A。如果您确实是这样做的,那么它将属于B::f(窗口)在A中,则它将属于B。因此,问题是,如果您没有将函数限定到它所属的位置,编译器将假定此函数的定义将在定义类的相同范围内。因此,编译器将假定隐式定义,并等待定义的链接时间,您将如果您没有提供链接错误,将出现链接错误。