新书这个例子,我再现参数相关查找(ADL)例如,在396和Stroustrup的书(第4版)的397页下面给出一些澄清:我需要相关的Stroustrup的约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
,其具有类型N::S
不是D
类的成员,也不其基Base
的。但它是namespace N
的成员。根据上面的第二个项目符号,函数N::f(S)
应该是所调用的函数,而不是Base::f()
。
以上也结果似乎不与在标准中段落3.4.2p2第二子弹,它说同意:
如果T是一个类类型(包括工会),其相关联的类是: 该课程本身;它是其成员的类别(如果有的话);和它的 直接和间接基类。其关联的名称空间是其关联的类是其成员的名称空间的 。此外,如果T是类模板专业化,则其关联的名称空间和类别还包括:与为模板类型参数 (不包括模板模板参数)提供的模板参数类型相关联的名称空间和类。任何 模板模板参数都是成员的名称空间;以及用作模板模板参数的任何 成员的类都是成员。
只有在通过常规查找找不到函数时,ADL才会开始运行。 –
@ n.m不正确。规则是如果正常查找找到本地实际函数声明(即'{void f(); ..')或类成员函数,则ADL被禁用。所有其他正常发现的声明(包括本地使用声明)仍然允许ADL完成。 –
@ n.m。如果这是真的,那么当你在全局命名空间中为你的类实现'operator <<'时,你将不能再编写'std :: cout << std :: string(“Hello”);'。这当然不会发生。 –