哪个命名空间确实包含此友元函数的声明?

时间:2014-09-05 19:05:58

标签: c++ c++11 namespaces lookup argument-dependent-lookup

普通查找(第7.3.1.2 / 3节)找不到下面的friend函数,但是ADL(§3.4.2/ 4第二个项目符号点)找到了f函数,因此代码编译并正常执行(live example)。但是函数f(x);未在任何名称空间中声明。例如,如果您尝试通过这些调用::f(x);A::f(x);A::X::f(x);替换来电#include <iostream> namespace A { class X { int i; friend void f(X x) { std::cout << x.i << '\n'; } public: X():i(101){} }; } int main() { A::X x; f(x); } ,则代码将无法编译。哪个命名空间确实包含此友元函数的声明?标准是否对此有所说明?

{{1}}

1 个答案:

答案 0 :(得分:5)

来自C ++标准

11.3朋友

  

6如果和,可以在类的朋友声明中定义函数   只有当类是非本地类(9.8)时,函数名才是   不合格,该函数具有命名空间范围。 [例如:

class M { friend void f() { } // definition of global f, a friend of M,
                              // not the definition of a member function
};
  

-end example]

另一个引用(7.3.1命名空间定义)

  

3在名称空间中首先声明的每个名称都是其成员   命名空间。如果非本地类中的朋友声明首先声明   朋友是一个类,函数,类模板或函数模板98   最内层封闭命名空间的成员。 朋友声明   本身不会使名称对非限定查找可见(3.4.1)   或合格的查找(3.4.3)。 [注意:朋友的名字将是   如果在提供匹配的声明,则在其命名空间中可见   命名空间范围(在类定义授予之前或之后)   友谊)。 -end note] 如果朋友的功能或功能模板是   调用时,可以通过查找的名称查找找到其名称   来自名称空间的函数和与类型相关联的类   函数参数(3.4.2)。如果朋友声明中的名字是   既不是限定的也不是模板ID,声明是一个函数   或者是一个精心设计的类型说明符,查找是否确定   实体先前已宣布不得考虑任何范围   在最里面的封闭命名空间之外。 [注:其他形式的   朋友声明不能声明最里面的新成员   封闭命名空间,因此遵循通常的查找规则。 - 注意   ]

我想提一下,在括号中包含一个函数名会抑制依赖于参数的查找。

对于此代码

int main()
{
    A::X x;
    ( f )(x);
}

将找不到函数f。