问题描述
我在cpp参考文献中对此example感到困惑。
我认为普通+ ADL查找在两种情况下都会产生以下集合:f(char)(普通查找), f(int)/ f(E)(ADL查找,因为它考虑了来自POI的可见性)。 然后,重载分辨率将在第一种情况下选择f(E),在另一种情况下选择f(int)。
在这种情况下,您能告诉我到底发生了什么(查找,重载分辨率)吗?
非常感谢!
示例示例:
void f(char); // first declaration of f
template<class T>
void g(T t) {
f(1); // non-dependent name: lookup finds ::f(char) and binds it now
f(T(1)); // dependent name: lookup postponed
f(t); // dependent name: lookup postponed
// dd++; // non-dependent name: lookup finds no declaration
}
enum E { e };
void f(E); // second declaration of f
void f(int); // third declaration of f
double dd;
void h() {
g(e); // instantiates g<E>,at which point
// the second and the third uses of the name 'f'
// are looked up and find ::f(char) (by lookup) and ::f(E) (by ADL)
// then overload resolution chooses ::f(E).
// This calls f(char),then f(E) twice
g(32); // instantiates g<int>,at which point
// the second and the third uses of the name 'f'
// are looked up and find ::f(char) only
// then overload resolution chooses ::f(char)
// This calls f(char) three times
}
解决方法
ADL在与参数类型关联的名称空间(或类)中寻找功能。因此,如果您在命名空间enum E
中声明X
,则ADL将仅在命名空间X
中查找(请参见下面的内容)。int
的基本类型没有任何关联的命名空间。因此,基本类型的ADL永远找不到。
void f(char); // first declaration of f
template<class T>
void g(T t) {
f(1); // non-dependent name: lookup finds ::f(char) and binds it now
f(T(1)); // dependent name: lookup postponed
f(t); // dependent name: lookup postponed
// dd++; // non-dependent name: lookup finds no declaration
}
namespace X {
enum E { e };
void f(E); // second declaration of f
void f(int); // third declaration of f
}
double dd;
void f(int);//the global namespace is not associated to fundamental types
void h() {
//The associated scope of X::e is namespace X.
g(X::e); // instantiates g<E>,at which point
// the second and the third uses of the name 'f'
// are looked up and find ::f(char) (by lookup) and X::f(int) and X::f(E) (by ADL)
// then overload resolution chooses X::f(E).
// This calls f(char),then X::f(E) twice
//Fundamental types do not have any associated namespace
g(32); // instantiates g<int>,at which point
// the second and the third uses of the name 'f'
// are looked up and find ::f(char) only
// then overload resolution chooses ::f(char)
// This calls f(char) three times
}