C++ 我需要一些关于Stroustrup';s关于ADL的新书
我在下面重现Stroustrup书(第四版)第396页和第397页中给出的参数相关查找(ADL)示例: 上面的评论是正确的(我已经测试过了),但这似乎与作者在下一段中所说的不一致: 在该标准中,参数相关查找的规则采用了措辞 在相关名称空间方面(iso§3.4.2)。基本上:C++ 我需要一些关于Stroustrup';s关于ADL的新书,c++,c++11,argument-dependent-lookup,C++,C++11,Argument Dependent Lookup,我在下面重现Stroustrup书(第四版)第396页和第397页中给出的参数相关查找(ADL)示例: 上面的评论是正确的(我已经测试过了),但这似乎与作者在下一段中所说的不一致: 在该标准中,参数相关查找的规则采用了措辞 在相关名称空间方面(iso§3.4.2)。基本上: 如果参数是类成员,则关联的名称空间是类本身(包括其基类)和类的 封闭名称空间 如果参数是名称空间的成员,则关联的名称空间是封闭的名称空间 如果参数是内置类型,则没有关联的名称空间 在示例中,类型为N::S的x不是类D的成
- 如果参数是类成员,则关联的名称空间是类本身(包括其基类)和类的 封闭名称空间
- 如果参数是名称空间的成员,则关联的名称空间是封闭的名称空间
- 如果参数是内置类型,则没有关联的名称空间
N::S
的x
不是类D
的成员,也不是其基base
的成员。但它是名称空间N
的成员。根据上面的第二个项目符号,应该调用函数N::f(S)
,而不是Base::f()
上述结果似乎与标准第3.4.2p2段中的第二个项目符号不一致,该项目符号表示:
如果T是类类型(包括联合),则其关联类为:
班级本身;其所属类别(如有);及其
直接和间接基类。其关联的名称空间是
其关联类是其成员的名称空间。此外,,
如果T是一个类模板专门化,那么它的相关名称空间和
类还包括:与
为模板类型参数提供的模板参数的类型
(不包括模板参数);任何
模板参数是成员;还有哪一类
用作模板参数的成员模板是成员
3.4.2/3设X
为非限定查找(3.4.1)产生的查找集,设Y
为参数相关的查找集
查找(定义如下)。如果X
包含
- 类成员的声明,或
- 不是using声明的块作用域函数声明,或
- 既不是函数也不是函数模板的声明
因此,基本上,当普通查找发现成员函数或本地(块范围)函数声明(或非函数的内容)时,ADL不会启动。当普通查找找到一个独立的命名空间作用域函数时,或者当它什么也找不到时,它确实会启动。ADL仅在通过常规查找未找到该函数时才会启动。@n.m不正确。规则是,如果正常查找发现本地实际函数声明(即
{void f();…
)或类成员函数,则禁用ADL。所有其他正常查找到的声明(包括本地使用声明)仍然允许进行ADL。@n.m.如果这是真的,那么在您实现operator@JohannesSchaub-litb嗯,这就是我的意思。还有其他“正常发现”的吗声明?@Johanneschaub litb啊,好吧,我明白了,还有其他常见的声明。我的错。我会接受你的答案。但是我仍然不理解3.4.2p3中的例子:g(parm,1)
,1是一个int,而不是float!有一个extern void g(NS::t,float)的局部(块范围)声明main
中的
。这将抑制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
}
};