ADL是调用朋友内联函数的唯一方法吗? [英] Is ADL the only way to call a friend inline function?
问题描述
让我们在S
的声明内将f
定义为S
的朋友函数:
Let us define f
, as a friend function of S
, inside the declaration of S
:
struct S
{
friend void f() {}
};
我找不到呼叫f
的方法.
是真的,那么这样的内联好友函数只能使用参数依赖查找上的title ="ADL ?
Is it true, then, that such an inline friend function can only be called with 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
怎么办?
Bonus: what if I want to get a function-pointer/std::function
/lambda to g
?
推荐答案
那么,这样的内联好友函数只能通过依赖于参数的查找来调用吗?
Is it true, then, that such an inline friend function can only be called with argument-dependant lookup?
是的.如 [namespace.memdef]/3 中所指定:>
Yes. As specified in [namespace.memdef]/3:
如果非本地类中的
friend
声明首先声明了一个类, 函数,类模板或函数模板.朋友是会员 最内层的封闭命名空间.朋友声明不 本身会使名称可见以进行不合格的查找 ([basic.lookup.qual)]或合格的查找([basic.lookup.qual]).
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
的 only 声明是其内联定义,因此对于合格或不合格的查找均不可见.但是,ADL对此类朋友功能有特殊规定, [基本. lookup.argdep]/4 :
Since the only declaration of f
is its inline definition, it's not made visible to qualified or unqualified lookup. ADL however, has a special provision for such friend functions, [basic.lookup.argdep]/4:
在考虑关联的名称空间时,查找与 当关联的名称空间用作 限定符([namespace.qual]),除了:
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:
- 在关联类中声明的任何命名空间范围的朋友函数或朋友函数模板在它们各自的内部可见 命名空间,即使它们在普通查找过程中不可见 ([class.friend]).
- 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应该这样做:
As for your bonus question, a lambda should do it:
auto exposed_g = [](S const& s){ g(s); };
它将ADL包装到其主体中.尽管适用有关归还类型扣除的常见警告.这将是一个值(假设您不返回void
).
It wraps the ADL into its body. Though the usual caveats about return type deduction apply. It will be a value (assuming you don't return void
).
这篇关于ADL是调用朋友内联函数的唯一方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!