友元定义函数的命名空间是什么?
What is the namespace of a friend-defined function?
如果我在 class 中定义了一个 friend 函数。 那个函数的命名空间是什么?
namespace A{namespace B{
struct S{
friend void f(S const&){};
};
}}
int main(){
A::B::S s{};
f(s); // ok
::f(s); // not ok, no f in global namespace
A::B::f(s); // no f in A::B
A::B::S::f(s); // not ok, no f in A::B::S
}
它有命名空间吗?
它有一个命名空间有意义吗?
如果我想消除常用成语中的调用歧义怎么办?
using std::swap;
swap(a, b);
我是否被迫在 class 之外定义它并声明它为朋友?
是的,你在外面定义了一个函数,让它成为某个class的友元。它是绝对独立的函数,但你允许它访问某些class。
在命名空间中首次声明的每个名称都是该命名空间的成员。如果非本地 class 中的友元声明首先声明一个 class 或函数,则友元 class 或函数是最内层封闭命名空间的成员。
友元声明引用来自最窄封闭命名空间的函数。但是,它没有将那个函数的名称引入到命名空间
9.3.1.2 Namespace member definitions
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 or qualified lookup.
http://eel.is/c++draft/namespace.memdef#3
所以,在你的情况下 A::B::f
是朋友。但是,名称 f
还不存在于 A::B
中。在 A::B
.
中明确声明 f
之前,您将无法将其称为 A::B::f
名称查找能够通过称为 Argument Dependent Lookup (ADL) 的特殊机制在不合格的 f(s)
调用中找到 f
。 ADL 是唯一可以 "see" 您的功能的机制。
该函数在 A::B
中,但只能通过 ADL 或 Koenig Lookup 找到。
它在 main 中命名的唯一方法是在 class 定义之外引入它。
是的,这很奇怪。
namespace A{namespace B{
inline void f(S const&);
struct S{
friend void f(S const&){};
};
}}
现在 A::B::f
命名 f
。
这个技巧是我用来介绍运算符和其他自定义点的东西。它还允许在本身不是模板的模板 classes 上创建每个模板实例函数。
template<class T>
struct foo {
friend void not_a_template( T ){}
};
template<class T>
void is_a_template(T){}
如果我在 class 中定义了一个 friend 函数。 那个函数的命名空间是什么?
namespace A{namespace B{
struct S{
friend void f(S const&){};
};
}}
int main(){
A::B::S s{};
f(s); // ok
::f(s); // not ok, no f in global namespace
A::B::f(s); // no f in A::B
A::B::S::f(s); // not ok, no f in A::B::S
}
它有命名空间吗? 它有一个命名空间有意义吗?
如果我想消除常用成语中的调用歧义怎么办?
using std::swap;
swap(a, b);
我是否被迫在 class 之外定义它并声明它为朋友?
是的,你在外面定义了一个函数,让它成为某个class的友元。它是绝对独立的函数,但你允许它访问某些class。
在命名空间中首次声明的每个名称都是该命名空间的成员。如果非本地 class 中的友元声明首先声明一个 class 或函数,则友元 class 或函数是最内层封闭命名空间的成员。
友元声明引用来自最窄封闭命名空间的函数。但是,它没有将那个函数的名称引入到命名空间
9.3.1.2 Namespace member definitions
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 or qualified lookup.
http://eel.is/c++draft/namespace.memdef#3
所以,在你的情况下 A::B::f
是朋友。但是,名称 f
还不存在于 A::B
中。在 A::B
.
f
之前,您将无法将其称为 A::B::f
名称查找能够通过称为 Argument Dependent Lookup (ADL) 的特殊机制在不合格的 f(s)
调用中找到 f
。 ADL 是唯一可以 "see" 您的功能的机制。
该函数在 A::B
中,但只能通过 ADL 或 Koenig Lookup 找到。
它在 main 中命名的唯一方法是在 class 定义之外引入它。
是的,这很奇怪。
namespace A{namespace B{
inline void f(S const&);
struct S{
friend void f(S const&){};
};
}}
现在 A::B::f
命名 f
。
这个技巧是我用来介绍运算符和其他自定义点的东西。它还允许在本身不是模板的模板 classes 上创建每个模板实例函数。
template<class T>
struct foo {
friend void not_a_template( T ){}
};
template<class T>
void is_a_template(T){}