是否可以有一个只能通过 ADL 找到的非友元函数?

gez*_*eza 4 c++ declaration friend-function name-lookup unqualified-name

C++ 有一个特性,类内定义的友元函数只能通过 ADL(参数相关查找)找到:

struct Foo {
    friend void fn(Foo) { } // fn can only be called by ADL, it won't be found by other lookup methods
};
Run Code Online (Sandbox Code Playgroud)

对于非友元函数是否可以实现相同的效果?我问这个问题是因为有时,我希望拥有“仅由 ADL 找到”的功能,但我实际上并不需要朋友访问类内部。

(还有一个有点固执己见的问题:如果这是不可能的,那么原因是什么?这个“仅由 ADL 发现”规则是故意设计到语言中的吗?)

Sto*_*ica 6

这只适用于友元函数,因为它们是唯一存在此措辞的函数。使函数对于普通名称查找不可见的措辞以及在 ADL 期间考虑它们的措辞都仅适用于此类朋友。

该功能实际上是为了替换另一个被认为问题较多的功能而引入的。N0777是详细介绍它的论文。模板用于在实例化模板时将其友元函数名称注入作用域,以便通过常规名称查找找到。这并不理想,并且导致了重载解析方面的问题。

该功能原本打算删除,但它是Barton-Nackman 技巧的支柱,因此提出了一种解决方案,最终成为我们所知的仅由 ADL 查找的内联友元函数。它是为了方便编程习惯而定制的。

由于此后没有提出需要这种行为的其他广泛传播的习惯用法,因此这种行为没有扩展到非友元函数。