友元函数名称的名称查找规则是什么?
如果非本地类中的
friend
声明首先声明一个类、函数、类模板或函数模板,则该friend是最内部封闭命名空间的成员。
我认为编译器必须执行名称查找来确定友元声明是否首先声明一个函数。也就是说,编译器将尝试查找与 friend
声明相对应的实体。但我在标准中没有找到任何描述该查找规则的内容。
标准中上述内容之后的文字说
如果友元声明中的名称既不是限定的也不是模板 ID,并且该声明是函数或详细类型说明符,则用于确定该实体是否先前已声明的查找不应考虑该实体之外的任何范围。最里面的封闭命名空间。
来自 cppreference:
对于友元声明,确定其是否引用先前声明的实体的查找按上面的方式进行,只不过它在最内部的封闭命名空间之后停止。
其中“above”指的是类定义中非限定名称的查找规则。
所以我写了一个小例子来测试我的想法:
struct A {
static void fun(A) { }
friend void fun(A);
};
fun(A{});
这里对 fun
的调用将在 struct A 中找到
通过 ADL。我在 clang 上测试了代码,它引发了链接器错误(godbolt):friend
函数 fun
对“fun(A)”的未定义引用
这证明了友元函数fun
与静态成员函数fun
没有关系。
然而,根据 cppreference,名称 fun
应该首先在类中查找。我不知道为什么这里找不到静态成员fun
。好吧,我同意这是一个荒谬的解释,但我找不到反驳该解释的标准文本。
那么编译器按照什么规则来查找友元声明对应的实体呢?
According to [namespace.memdef]#3:
If a
friend
declaration in a non-local class first declares a class, function, class template or function template the friend is a member of the innermost enclosing namespace.
I think the compiler has to perform name lookup to determine if the friend declaration first declares a function. That is, the compiler will try to find the entity corresponding to the friend
declaration. But I didn't find anything in the standard describing that lookup rule.
The text following the above in the standard says
If the name in a friend declaration is neither qualified nor a template-id and the declaration is a function or an elaborated-type-specifier, the lookup to determine whether the entity has been previously declared shall not consider any scopes outside the innermost enclosing namespace.
From cppreference:
For a friend declaration, the lookup to determine whether it refers to a previously declared entity proceeds as above except that it stops after the innermost enclosing namespace.
where "above" refers to the lookup rules for unqualified names in class definitions.
So I wrote a small example to test my idea:
struct A {
static void fun(A) { }
friend void fun(A);
};
fun(A{});
Here the call to fun
will find the friend
function fun
within the struct A
via ADL. I tested the code on clang and it throws a linker error(godbolt):
undefined reference to `fun(A)'
This proves that the friend function fun
is not related to the static member function fun
.
However, according to cppreference, the name fun
should be looked up within the class first. I don't know why the static member fun
cannot be found here. Well, I agree that this is a ridiculous explanation, but I can't find a standard text that refutes that explanation.
So what rules does the compiler follow to find the entity corresponding to the friend declaration?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论