代码之家  ›  专栏  ›  技术社区  ›  alfC

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

  •  3
  • alfC  · 技术社区  · 6 年前

    如果在类中有一个定义为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);
    

    我是不是被迫在类外定义它并将其声明为朋友?

    3 回复  |  直到 6 年前
        1
  •  6
  •   AnT stands with Russia    6 年前

    朋友宣言 从最窄的封闭命名空间到函数。然而, 它没有引入该函数的名称 进入命名空间

    9.3.1.2命名空间成员定义
    如果非本地类中的友元声明首先声明类、函数、类模板或函数模板,则友元是最内层封闭命名空间的成员。朋友声明本身并不能 非限定查找或限定查找可见的名称。

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

    所以,对你来说 A::B::f 是朋友但是,name f 不存在于 A::B 但是你不能称之为 A::B::f 除非你明确声明 f型 在里面 甲:乙 是的。

    名称查找能够找到 f型 不合格 f(s) 通过一种叫做 Argument Dependent Lookup (ADL)ADL是唯一能“看到”你的功能的机制。

        2
  •  3
  •   Yakk - Adam Nevraumont    6 年前

    函数在 A::B 但它只能通过adl或koenig查找找到。

    在main中命名它的唯一方法是在类定义之外引入它。

    是的,这很奇怪。

    namespace A{namespace B{
      inline void f(S const&);
      struct S{
        friend void f(S const&){};
      };
    }}
    

    现在 A::B::f 姓名 f 是的。

    这种技术是我用来介绍操作员和其他定制点的它还允许在本身不是模板的模板类上创建每个模板实例函数。

    template<class T>
    struct foo {
      friend void not_a_template( T ){}
    };
    template<class T>
    void is_a_template(T){}
    
        3
  •  1
  •   PStarczewski    6 年前

    是的,您在外部定义函数并使其成为某个类的朋友它是绝对独立的函数,但允许它访问特定的类。

    名称空间中首先声明的每个名称都是该名称空间的成员。如果非本地类中的友元声明首先声明了类或函数,则友元类或函数是最内层封闭命名空间的成员。