友元函数名称的名称查找规则是什么?

发布于 2025-01-09 03:19:10 字数 1397 浏览 2 评论 0原文

根据 [namespace.memdef]#3

如果非本地类中的friend声明首先声明一个类、函数、类模板或函数模板,则该friend是最内部封闭命名空间的成员。

我认为编译器必须执行名称查找来确定友元声明是否首先声明一个函数。也就是说,编译器将尝试查找与 friend 声明相对应的实体。但我在标准中没有找到任何描述该查找规则的内容。

标准中上述内容之后的文字说

如果友元声明中的名称既不是限定的也不是模板 ID,并且该声明是函数或详细类型说明符,则用于确定该实体是否先前已声明的查找不应考虑该实体之外的任何范围。最里面的封闭命名空间。

来自 cppreference

对于友元声明,确定其是否引用先前声明的实体的查找按上面的方式进行,只不过它在最内部的封闭命名空间之后停止。

其中“above”指的是类定义中非限定名称的查找规则。

所以我写了一个小例子来测试我的想法:

struct A {
  static void fun(A) { }
  friend void fun(A);
};

fun(A{});

这里对 fun 的调用将在 struct A 中找到 friend 函数 fun 通过 ADL。我在 clang 上测试了代码,它引发了链接器错误(godbolt):

对“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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文