1

[basic.lookup.argdep]/3中的示例:

namespace NS {
    class T { };
    void f(T);
    void g(T, int);
}
NS::T parm;
void g(NS::T, float);
int main() {
    f(parm); // OK: calls NS::f
    extern void g(NS::T, float);
    g(parm, 1); // OK: calls g(NS::T, float)
}

对于调用g(parm, 1),我们在集合X中具有全局范围内的声明void g(NS::T, float);。AFAICT,我们在集合Yvoid g(T, int);中也有namespace中的声明,这是 typeNS参数的关联命名空间。因此,如果我没记错的话,这两个声明是重载解决方案的候选者。那么,与命名空间中的声明相比,全局范围内的声明是否更受欢迎?为什么?我非常感谢标准的引用作为答案。parmNS::TNS

4

1 回答 1

2

在该部分中,我们有:

X为非限定查找产生Y的查找集,令 为由参数依赖查找产生的查找集(定义如下)。如果X包含

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

然后Y是空的。

非限定查找找到块作用域函数声明 - extern void g(NS::T, float)。不是全局范围的声明::g

因此,Y是空的,这使得 和 的X并集很简单,Y它只X包含一个声明,这是一个可行的候选者。

如果该声明不存在,则将找到不合格的查找,然后void g(NS::T, float)我们将继续执行 ADL,这将找到N::g(T, int),这是一个更好的匹配。

于 2018-08-03T21:54:06.437 回答