模板函数中的名称查找规则

q09*_*987 9 c++ templates c++11

#include <iostream>
using namespace std;

template<typename T>
void adl(T)
{
  cout << "T";
}

struct S
{
};

template<typename T>
void call_adl(T t)
{
  adl(S());
  adl(t);
}

void adl(S)
{
  cout << "S";
}

int main ()
{
  call_adl(S());
}
Run Code Online (Sandbox Code Playgroud)

为什么结果是"TS"?模板函数中的名称查找规则是什么?

http://ideone.com/sB3DnL

Jon*_*ely 9

模板在定义和实例化点的两个阶段进行编译.第一个阶段发生在编译器首次处理模板定义时,一些名称立即绑定到定义.在实例化模板之前,某些名称保持未绑定状态,因为它们依赖于模板参数,因此在实例化模板并且模板参数已知之前无法查找.

在这个电话中:

adl(S());
Run Code Online (Sandbox Code Playgroud)

没有任何东西依赖于函数的模板参数,因此立即完成查找(在第一阶段期间)并且它找到唯一被调用的函数adl,该函数在该点的范围内.

在这个电话中:

adl(t);
Run Code Online (Sandbox Code Playgroud)

取决于类型,t因此查找被延迟,直到t知道类型的实例化.当你在范围内调用call_adl(S())第二个重载时adl,所以当adl(t)调用执行名称查找时,范围内还有另一个函数,它更适合参数.

  • [temp.point] p8"翻译单元的末尾也被视为实例化点",即文件中的所有声明在第2阶段都可见. (2认同)