关于Stroustrup关于ADL的新书,我需要对这个例子做一些澄清

时间:2013-10-06 13:36:10

标签: c++ c++11 argument-dependent-lookup

我在Stroustrup book(第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的{​​{1}}不是类N::S的成员,也不是其基类D的成员。但它是Base的成员。根据上面的第二个项目,函数namespace N应该是被调用的函数,而不是N::f(S)

上述结果似乎也不符合标准第3.4.2p2段中的第二个子弹,该子弹说:

  

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

1 个答案:

答案 0 :(得分:4)

  

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

     
      
  • 类成员的声明,或
  •   
  • 块范围函数声明,它不是using声明或
  •   
  • 既不是函数也不是函数模板的声明
  •   
     

然后Y为空。否则...

基本上,当普通查找找到成员函数或本地(块范围)函数声明(或者不是函数的东西)时,ADL不会启动。当普通查找找到一个独立的命名空间范围函数,或者什么都没找到时,它确实会启动。