这段代码基本上不会编译
struct M
{
static void staticF(M m) {}
friend void friendF(M m) {}
};
int main()
{
M::staticF({}); //< okay
M m;
friendF(m); //< okay
friendF({}); //< error: doesn't the compiler allow this?
}
编译器说friendf
“未在作用域中声明”。
请尝试代码:https://godbolt.org/z/8mq664
问题不在于{}
,而在于编译器所说的:函数没有在试图调用它的作用域中声明。添加声明:
struct M
{
static void staticF(M m) {}
friend void friendF(M m) {}
};
void friendF(M m);
int main()
{
M::staticF({}); //< okay
M m;
friendF(m); //< okay
friendF({}); //< okay
}
friendf(m);
在没有声明的情况下也能工作的原因是参数相关查找(ADL)。简而言之:编译器根据friendf
参数的声明位置来查找它。
请注意,通常,友元声明只是声明,定义通常在类之外提供:
struct M
{
static void staticF(M m) {}
void friendF(M m);
};
void friendF(M m) {}
如果函数只在类的作用域中使用,那么它可以是私有成员。
这样试试
struct M
{
static void staticF(M m) {}
friend void friendF(M m);
};
void friendF(M m) {}
int main()
{
M::staticF({}); //< okay
M m;
friendF(m); //< okay
friendF({}); //< okay
}
friend
函数使用与ADL类似的规则。
所以只有在提供了M
类型时才能找到您的函数。
{}
没有类型。
可能的解决方案是在类外声明函数:
struct M
{
static void staticF(M m) {}
friend void friendF(M m) {}
};
void friendF(M m); // Now visible from outside
演示