我在 Stroustrup 书(第 4 版)第 396 页和第 397 页中给出的参数相关查找(ADL)示例下方重现:
namespace N {
struct S { int i; };
void f(S);
void g(S);
void h(int);
};
struct Base {
void f(N::S);
};
struct D : Base {
void mf(N::S);
void g(N::S x)
{
f(x); // call Base::f()
mf(x); // call D::mf()
h(1); // error: no h(int) available
}
};
上面的评论说的是正确的(我已经测试过了),但这似乎与作者在下一段中所说的不一致:
在标准中,依赖于参数的查找规则是根据关联的命名空间来表述的(iso §3.4.2)。基本上:
- 如果参数是类成员,则关联的命名空间是类本身(包括其基类)和类的封闭命名空间。
- 如果参数是命名空间的成员,则关联的命名空间是封闭的命名空间。
- 如果参数是内置类型,则没有关联的命名空间。
在示例中x
,具有 typeN::S
的 不是 class 的成员D
,也不是其 base的成员Base
。但它是namespace N
. 根据上面的第二个项目符号,该函数N::f(S)
应该是被调用的函数,而不是Base::f()
.
上面的结果似乎也与标准中第 3.4.2p2 段中的第二个项目符号不一致,其中说:
如果 T 是类类型(包括联合),则其关联的类是:类本身;它所属的类别(如有的话);及其直接和间接基类。其关联名称空间是其关联类是其成员的名称空间。此外,如果 T 是类模板特化,则其关联的命名空间和类还包括: 与为模板类型参数(不包括模板模板参数)提供的模板实参类型相关联的命名空间和类;任何模板模板参数都是其成员的命名空间;以及用作模板模板参数的任何成员模板是其成员的类。