在我看来,在 [basic.lookup.argdep]/3 中的示例中,调用 g(parm, 1) 有两个候选函数
It seems to me that there are two candidate functions for the call g(parm, 1) in the example in [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,我们在集合 Y 中还有命名空间 NS
中的声明 void g(T, int);
,类型为 [=17= 的参数 parm
的关联命名空间].因此,如果我没记错的话,这两个声明是重载决议的候选者。那么,与命名空间 NS
中的声明相比,全局范围中的声明是否更受青睐?为什么?我非常感谢引用标准中的一句话作为答案。
在那个部分,我们有:
Let X
be the lookup set produced by unqualified lookup and let Y
be the lookup set produced by argument dependent lookup (defined as follows). If X
contains
- a declaration of a class member, or
- a block-scope function declaration that is not a using-declaration, or
- a declaration that is neither a function nor a function template
then Y
is empty.
非限定查找找到块作用域函数声明 - extern void g(NS::T, float)
。不是全局范围的声明 ::g
.
因此,Y
是空的,这使得 X
和 Y
的联合简单地只是 X
,它只包含一个声明,这是一个可行的候选人。
如果该声明不存在,则非限定查找会找到 void g(NS::T, float)
,我们将继续执行 ADL,这会找到更好的匹配 N::g(T, int)
。
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,我们在集合 Y 中还有命名空间 NS
中的声明 void g(T, int);
,类型为 [=17= 的参数 parm
的关联命名空间].因此,如果我没记错的话,这两个声明是重载决议的候选者。那么,与命名空间 NS
中的声明相比,全局范围中的声明是否更受青睐?为什么?我非常感谢引用标准中的一句话作为答案。
在那个部分,我们有:
Let
X
be the lookup set produced by unqualified lookup and letY
be the lookup set produced by argument dependent lookup (defined as follows). IfX
contains
- a declaration of a class member, or
- a block-scope function declaration that is not a using-declaration, or
- a declaration that is neither a function nor a function template
then
Y
is empty.
非限定查找找到块作用域函数声明 - extern void g(NS::T, float)
。不是全局范围的声明 ::g
.
因此,Y
是空的,这使得 X
和 Y
的联合简单地只是 X
,它只包含一个声明,这是一个可行的候选人。
如果该声明不存在,则非限定查找会找到 void g(NS::T, float)
,我们将继续执行 ADL,这会找到更好的匹配 N::g(T, int)
。