【发布时间】:2020-11-20 21:47:31
【问题描述】:
以下程序编译(live demo),但我不明白,为什么。
namespace N {
struct S {};
}
void Foo(N::S);
namespace Lib {
template <class T>
void Call() { Foo(T{}); }
void Foo();
}
int main()
{
Lib::Call<N::S>();
}
Lib::Foo不应该隐藏::Foo吗? Call 中的Foo 是一个依赖名称,并且依赖名称的评估应该推迟到模板的实例化。在这种情况下,名称查找如何工作?
在命名空间Lib中Foo(N::S{})可以在void Foo();声明之前调用,但不能在声明之后调用,因为Lib::Foo隐藏了::Foo。 Lib::Call<N::S>(); 在声明之后,所以在这里绑定名称Foo 时,隐藏应该是有效的,不是吗?
【问题讨论】:
-
我不太确定,但经过一番研究:如果
Foo是非依赖的,则在模板定义上下文中执行普通查找和ADL。如果Foo是依赖的,则在模板定义上下文中执行普通查找,但在实例化点执行 ADL。我们的情况是第二种,因此::Foo是通过普通查找找到的。Lib::Foo声明不会隐藏::Foo,因为它位于普通查找搜索的上下文之后。有人请确认我的假设,也许在答案中。
标签: c++ language-lawyer name-lookup