朋友定义的函数的命名空间是什么?

alf*_*lfC 3 c++ overloading namespaces friend-function c++11

如果我在一个类中定义了一个函数.该函数的命名空间是什么?

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
}
Run Code Online (Sandbox Code Playgroud)

它甚至有名称空间吗?拥有命名空间是否有意义?

如果我想消除常用习语中的呼叫,该怎么办?

using std::swap;
swap(a, b);
Run Code Online (Sandbox Code Playgroud)

我是否被迫在课外定义并宣布为朋友?

AnT*_*AnT 6

友元声明是指来自最窄的封闭命名空间的函数.但是,它不会将该函数的名称引入名称空间

9.3.1.2命名空间成员定义
3如果非本地类中的友元声明首先声明了类,函数,类模板或函数模板,则该友元是最内层封闭命名空间的成员.友元声明本身不会使名称对非限定查找或限定查找可见.

http://eel.is/c++draft/namespace.memdef#3

所以,在你的情况下A::B::f是一个朋友.但是,名称f尚不存在A::B.你将不能够把它称为A::B::f,直到你提供一个明确的声明fA::B.

名称查找能够通过名为Argument Dependent Lookup(ADL)的特殊机制f在非限定f(s)调用中查找.ADL是唯一可以"看到"您的功能的机制.