让我们在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
的 only 声明是它的内联定义,因此它对合格或不合格的查找不可见。然而,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++ - ADL 是调用 friend 内联函数的唯一方法吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51304560/