成员函数的依赖非限定名称的 C++ 两阶段查找
C++ two-phase lookup for dependent unqualified name of member function
Josuttis 和 Vandervoorde 提到,对于依赖的非限定名称,编译器在第一阶段应用普通查找,在第二阶段应用 ADL。然后它结合了重载集。像这样:
struct B{};
void bar(int){} // first overload
template <class T>
void foo(T t)
{
bar(2, t);
}
void bar(int, B){} // second overload
int main() {
foo(B{}); // works just fine, calls second overload
}
但是如果从属名是成员函数的名字那么这个原则就不起作用了:
struct B{};
struct A{
template <class T>
void foo(T t)
{
bar(2, t);
}
void bar(int){} // first overload
};
void bar(int, B){} // second overload
int main() {
A a;
a.foo(B{}); // gives error
}
这是为什么?
我想知道是否有人可以指出 Standard
的注释
我在标准中找到了一个声明
3.4.2:
Let X be the lookup set produced by unqualified lookup and let Y be
the lookup set produced by argument dependent lookup. If X contains:
a declaration of class member, or
a block-scope function declaration that is not a using-declaration, or
- a declaration that is neither a function or a function template
then Y is empty.
Josuttis 和 Vandervoorde 提到,对于依赖的非限定名称,编译器在第一阶段应用普通查找,在第二阶段应用 ADL。然后它结合了重载集。像这样:
struct B{};
void bar(int){} // first overload
template <class T>
void foo(T t)
{
bar(2, t);
}
void bar(int, B){} // second overload
int main() {
foo(B{}); // works just fine, calls second overload
}
但是如果从属名是成员函数的名字那么这个原则就不起作用了:
struct B{};
struct A{
template <class T>
void foo(T t)
{
bar(2, t);
}
void bar(int){} // first overload
};
void bar(int, B){} // second overload
int main() {
A a;
a.foo(B{}); // gives error
}
这是为什么? 我想知道是否有人可以指出 Standard
的注释我在标准中找到了一个声明 3.4.2:
Let X be the lookup set produced by unqualified lookup and let Y be the lookup set produced by argument dependent lookup. If X contains:
a declaration of class member, or
a block-scope function declaration that is not a using-declaration, or
- a declaration that is neither a function or a function template
then Y is empty.