c++ - 隐藏的 friend : declarations and definitions

标签 c++ friend argument-dependent-lookup

在他最近的 blog post安东尼威廉姆斯谈论隐藏的 friend 。如果我理解正确的话,主要思想是在某些情况下 ADL 无法找到声明为友元的函数。简单示例:

namespace N {
    struct A {
        friend void foo(A) { }
    };

    struct B {
        operator A();
    };

    // (*)
    void bar(A) { }
}

void func() {
    N::A a;
    bar(a);   // OK, bar is found via ADL
    foo(a);   // OK, foo is found via ADL

    N::B b;
    bar(b);   // OK, bar is found via ADL
    foo(b);   // NOT OK, foo cannot be found
}

在博文中的所有示例中,友元函数都是在类中定义的。是否可以声明一个友元函数,然后在 (*) 处定义它,使其保持隐藏?看起来隐藏的 friend 只能在类范围内(或在另一个编译单元中)定义。

最佳答案

隐藏的 friend 需要完全内联定义,即在类定义的内部。是的,如果您在其他地方定义 friend ,定义可能会导致 namespace 可见性,它将打破基于隐藏 friend 的限制,这些隐藏 friend 只能通过 ADL 搜索找到匹配项,因此成为重载解析的候选对象。

更多信息请参见 WG21 recommendations用于指定隐藏的 friend , 注意到隐藏的 friend 是完全内联定义的,就像这个片段:

#include <ostream>
#include <compare>
class C  {
    friend ostream& operator << ( ostream&, C const& )  {}
    friend auto   operator <=>( C const&, C const& )  = default;
};

关于c++ - 隐藏的 friend : declarations and definitions,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56795676/

相关文章:

c++ - 在我看来,[basic.lookup.argdep]/3 中的示例中有两个候选函数用于调用 g(parm, 1)

c++ - C++ 中的类模板和友元

c++ - 函数对象转换为函数指针

C++ 和类对象名称

c++ - 从源文件中定义的类访问 header 中定义的类的私有(private)变量

c++ - 私有(private)枚举访问无法从嵌套类的友元函数编译

c++ - protobuf 与 zeromq 与 C++ 的链接错误

c++ - 具有全局成员歧义的静态数据成员定义

c++ - 无法为命名空间中的私有(private)枚举重载 i/o 运算符

C++ 奇怪的模板/命名空间行为