找到了什么功能

通过首先收集一组 关联类关联命名空间 来找到函数,这些命名空间包括以下一个或多个,具体取决于参数类型 T。首先,让我们展示类,枚举和类模板特化名称的规则。

  • 如果 T 是嵌套类,成员枚举,那么它的周围类。
  • 如果 T 是一个枚举(这可能成为一个类的成员!),它的最里面的命名空间。
  • 如果 T 是一个类(它可能可以嵌套!),它的所有基类和类本身。所有关联类的最内层命名空间。
  • 如果 TClassTemplate<TemplateArguments>(这也是一个类!),与模板类型参数关联的类和命名空间,任何模板模板参数的命名空间和任何模板模板参数的周围类,如果模板参数是成员模板。

现在,内置类型也有一些规则

  • 如果 T 是指向 UU 数组的指针,则与 U 相关联的类和名称空间。示例:void (*fptr)(A); f(fptr);,包括与 void(A) 关联的名称空间和类(请参阅下一条规则)。
  • 如果 T 是函数类型,则与参数和返回类型相关联的类和名称空间。示例:void(A) 将包含与 A 关联的名称空间和类。
  • 如果 T 是指向成员的指针,则与成员类型关联的类和名称空间(可以应用于指向成员函数的指针和指向数据成员的指针!)。示例:B A::*p; void (A::*pf)(B); f(p); f(pf); 包含与 ABvoid(B) 相关的名称空间和类(对于函数类型应用了上面的项目符号)。

*所有关联命名空间中的所有函数和模板都可通过参数依赖查找找到。*此外,还会找到在关联类中声明的命名空间范围友元函数,这些函数通常不可见。但是,使用指令会被忽略。

以下所有示例调用都是有效的,而不会通过调用中的命名空间名称限定 f

namespace A {
   struct Z { };
   namespace I { void g(Z); }
   using namespace I;

   struct X { struct Y { }; friend void f(Y) { } };
   void f(X p) { }
   void f(std::shared_ptr<X> p) { }
}

// example calls
f(A::X());
f(A::X::Y());
f(std::make_shared<A::X>());

g(A::Z()); // invalid: "using namespace I;" is ignored!