为什么这个友元函数不允许 brace-init-list 但静态函数允许?
Why doesn't this friend function allow brace-init-list but the static one does?
基本上这段代码不会编译
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
“未在范围内声明”。
试试这个方法
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
}
问题不在于 {}
,但正如编译器所说:该函数未在您尝试调用它的范围内声明。添加声明:
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);
在没有声明的情况下也能正常工作的原因是 Argument Dependent Lookup (ADL)。简而言之:编译器根据声明其参数的位置查找 friendF
。
请注意,通常朋友声明只是声明,定义通常在 class:
之外提供
struct M
{
static void staticF(M m) {}
void friendF(M m);
};
void friendF(M m) {}
如果该函数仅在class范围内使用,那么它可以是私有成员。
friend
函数使用与 ADL.
相似的规则
因此只有在提供类型 M
时才能找到您的函数。
{}
没有类型。
可能的解决方案是在 class 之外声明函数:
struct M
{
static void staticF(M m) {}
friend void friendF(M m) {}
};
void friendF(M m); // Now visible from outside
基本上这段代码不会编译
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
“未在范围内声明”。
试试这个方法
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
}
问题不在于 {}
,但正如编译器所说:该函数未在您尝试调用它的范围内声明。添加声明:
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);
在没有声明的情况下也能正常工作的原因是 Argument Dependent Lookup (ADL)。简而言之:编译器根据声明其参数的位置查找 friendF
。
请注意,通常朋友声明只是声明,定义通常在 class:
之外提供struct M
{
static void staticF(M m) {}
void friendF(M m);
};
void friendF(M m) {}
如果该函数仅在class范围内使用,那么它可以是私有成员。
friend
函数使用与 ADL.
因此只有在提供类型 M
时才能找到您的函数。
{}
没有类型。
可能的解决方案是在 class 之外声明函数:
struct M
{
static void staticF(M m) {}
friend void friendF(M m) {}
};
void friendF(M m); // Now visible from outside