什么时候发生非依赖名称的重载解析,在定义上下文或实例化点?

时间:2015-12-08 11:30:53

标签: c++ templates language-lawyer overload-resolution name-lookup

  

3.4 [basic.lookup] / p1

     

重载解析(13.3)在名称查找成功后发生。

void g(long);

void g(int, int);

template<class T> void f() { g(0); }

void g(int, int = 0) {}

int main(){
    f<int>();
}

gcc汇编成功,clang faild。

何时发生非依赖名称的重载解析,在定义上下文或实例化点?或两者都是对的?

2 个答案:

答案 0 :(得分:2)

在这两种情况下。

[temp.res] 14.6 \ 8

  

如果紧接着是模板的假设实例化   由于没有构造,它的定义将是不正确的   取决于模板参数,程序是不正确的;没有   诊断是必需的。如果解释这样的结构   假设的实例不同于解释   任何实际实例化中的相应构造   模板,该程序是不正确的;无需诊断。

[temp.nondep] 14.6.3 \ 1

  

模板定义中使用的非依赖名称可以使用   通常的名称查找和绑定在他们使用的点。

所以两个编译器都是对的。

答案 1 :(得分:0)

如果我对查找规则的理解是正确的,那么因为g()是一个非依赖名称,所以在第2阶段不会将重载集添加到。因此{{1}的唯一选择在定义点是g(0),而Clang是正确的。

考虑到定义的顺序,我肯定会天真地期望只考虑g(long),但是当涉及到模板时,C ++标准也不会直观。