我需要在Stroustrup关于ADL的新书中对这个例子进行一些澄清

I need some clarification regarding this example on Stroustrup's new book about ADL

本文关键字:Stroustrup 关于 新书中 ADL      更新时间:2023-10-16

我在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(。基本上:

  • 如果参数是类成员,则关联的命名空间是类本身(包括其基类(和类的 封闭命名空间。
  • 如果参数是命名空间的成员,则关联的命名空间是封闭的命名空间。
  • 如果参数是内置类型,则没有关联的命名空间。

在该示例中,类型为 N::Sx 不是类 D 的成员,也不是其基Base的成员。但它是namespace N的成员.根据上面的第二个项目符号,函数N::f(S)应该是调用的函数,而不是Base::f()

上面的结果似乎也与标准中第 3.4.2p2 段中的第二个项目符号不一致,该部分说:

如果 T 是类类型(包括联合(,则其关联的类为: 类本身;它所属的类别(如有(;及其 直接和间接基类。其关联的命名空间是 其关联类所属的命名空间。此外 如果 T 是类模板专用化,则其关联的命名空间和 类还包括:与 为模板类型参数提供的模板参数的类型 (不包括模板模板参数(;其中任何命名空间 模板模板参数是成员;以及其中任何类别 用作模板模板参数的成员模板是成员。

3.4.2/3X为非限定查找(3.4.1(生成的查找集,设Y参数依赖生成的查找集 查找(定义如下(。如果X包含

  • 集体成员的声明,或
  • 不是 using 声明的块作用域函数声明,或
  • 既不是函数也不是函数模板的声明

则 Y 为空。否则。。。

所以基本上,当普通查找找到成员函数或本地(块范围(函数声明(或不是函数的东西(时,ADL 不会启动。当普通查找找到独立的命名空间范围函数时,或者当它根本没有找到任何东西时,它确实会启动。