我有一个关于友元函数/类的问题。考虑以下代码:
#include <iostream>
struct A
{
private:
int a = 5;
friend int foo(A a);
};
int foo(A a)
{
return a.a;
}
int a = foo(A());
int main(){ std::cout << a << std::endl; }
演示
它运行正常,类范围内和全局范围内的int foo()
指向同一实体。尽管在类范围内声明int foo()
并没有在全局范围内引入名称。如果是这样,我们将在代码中收到链接错误而不是编译错误:
#include <iostream>
struct A
{
private:
int a = 5;
friend int foo();
};
int a = foo(); //undeclared foo
int main(){ std::cout << a << std::endl; }
在标准中我没有找到这方面的解释。它说的是 N3797:11.3/6 [class.friend]
:
如果且仅当类是非本地类(9.8),函数名未限定且具有命名空间作用域时,函数可以在类的友元声明中被定义。
因此,它解释了为什么下面的代码可以正常工作:
#include <iostream>
struct A
{
private:
int a = 5;
friend int foo(A a)
{
return a.a;
}
};
int a = foo(A());
int main(){ std::cout << a << std::endl; }
我们在友元声明中定义了函数,并且,正如标准所述,它成为了全局命名空间的成员。但是这个规则只涵盖定义,而不是声明。显然,并非所有的声明都是定义。因此,我们不能将其应用于第一个例子。