c – ADL是调用朋友内联函数的唯一方法吗?

让我们在S的声明中定义f作为S的友元函数:

struct S
{
    friend void f() {}
};

我找不到办法打电话给f.

那么,这样的内联朋友函数只能用argument-dependant lookup调用吗?

struct S
{
    friend void f() {}
    friend void g(S const&) {}
} const s;

int main()
{
    // f();     // error: 'f' was not declared in this scope
    // S::f();  // error: 'f' is not a member of 'S'
    g(s);
    // S::g(s); // error: 'g' is not a member of 'S'
}

额外奖励:如果我想获得函数指针/ std :: function / lambda到g怎么办?

解决方法:

Is it true, then, that such an inline friend function can only be called with argument-dependant lookup?

是.如[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. The friend declaration does not
by itself make the name visible to unqualified lookup
([basic.lookup.unqual]) or qualified lookup ([basic.lookup.qual]).

由于f的唯一声明是其内联定义,因此对于合格或不合格的查找不可见.但是,ADL对此类朋友功能有特殊规定,[basic.lookup.argdep]/4

When considering an associated namespace, the lookup is the same as
the lookup performed when the associated namespace is used as a
qualifier ([namespace.qual]) except that:

  • Any namespace-scope friend functions or friend function templates declared in associated classes are visible within their respective
    namespaces even if they are not visible during an ordinary lookup
    ([class.friend]).

至于你的奖金问题,lambda应该这样做:

auto exposed_g = [](S const& s){ g(s); };

它将ADL包裹在体内.虽然关于退货类型扣除的常见警告适用.它将是一个值(假设您没有返回void).

上一篇:c – 无法访问朋友ostream中的私人成员


下一篇:魔坊APP项目-13-好友列表、客户端显示页面(好友列表、添加好友)、服务端提供接口(模型创建、搜索用户信息)