让我们在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).