朋友功能的C ++内联定义

use*_*768 6 c++ friend language-lawyer

在C ++标准的最新草案(2019年3月)中[class.friend] p.6声明(重点是我):

仅当该类是非本地类([class.local]),函数名称不合格且该函数具有名称空间作用域时,才可以在该类的朋友声明中定义一个函数。[...]

“该函数具有名称空间范围”是什么意思?

在这种情况下,函数没有命名空间范围的唯一情况是:

struct A
{
    static void f();

    struct B
    {
        friend void f() {}; 
    }; 
};
Run Code Online (Sandbox Code Playgroud)

但是,clanggcc都不会将内部的friend定义与内部B的static方法关联A,而是与属于全局名称空间的函数关联。

还有其他情况我想念吗?

Ste*_*sen 3

我认为你实际上已经回答了你自己的问题,但你没有意识到。

“函数具有命名空间作用域”意味着它是命名空间的一部分,而不是类或结构的一部分。所以函数 A::B::f() 不存在。它也不引用 A::f() 。相反,您定义为友元的函数实际上是函数 ::f(),因为这是它所在的命名空间(全局命名空间)。

我怀疑(但没有尝试过),如果您将所有这些包装在一个名称空间中,那么您定义的 f() 将成为该名称空间的一部分。所以,举例来说,

namespace ns {
    struct A
    {
        static void f();

        struct B
        {
            friend void f() {}; 
        }; 
    };
}
Run Code Online (Sandbox Code Playgroud)

将把友元函数定义为函数 ns::f()。