C++ 我需要一些关于Stroustrup';s关于ADL的新书

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的成

我在下面重现Stroustrup书(第四版)第396页和第397页中给出的参数相关查找(ADL)示例:

上面的评论是正确的(我已经测试过了),但这似乎与作者在下一段中所说的不一致:

在该标准中,参数相关查找的规则采用了措辞 在相关名称空间方面(iso§3.4.2)。基本上:

  • 如果参数是类成员,则关联的名称空间是类本身(包括其基类)和类的 封闭名称空间
  • 如果参数是名称空间的成员,则关联的名称空间是封闭的名称空间
  • 如果参数是内置类型,则没有关联的名称空间
在示例中,类型为
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声明的块作用域函数声明,或
  • 既不是函数也不是函数模板的声明
那么Y是空的。否则


因此,基本上,当普通查找发现成员函数或本地(块范围)函数声明(或非函数的内容)时,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
    }
};