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。
何时发生非依赖名称的重载解析,在定义上下文或实例化点?或两者都是对的?
答案 0 :(得分:2)
在这两种情况下。
[temp.res] 14.6 \ 8
如果紧接着是模板的假设实例化 由于没有构造,它的定义将是不正确的 取决于模板参数,程序是不正确的;没有 诊断是必需的。如果解释这样的结构 假设的实例不同于解释 任何实际实例化中的相应构造 模板,该程序是不正确的;无需诊断。
[temp.nondep] 14.6.3 \ 1
模板定义中使用的非依赖名称可以使用 通常的名称查找和绑定在他们使用的点。
所以两个编译器都是对的。
答案 1 :(得分:0)
如果我对查找规则的理解是正确的,那么因为g()
是一个非依赖名称,所以在第2阶段不会将重载集添加到。因此{{1}的唯一选择在定义点是g(0)
,而Clang是正确的。
考虑到定义的顺序,我肯定会天真地期望只考虑g(long)
,但是当涉及到模板时,C ++标准也不会直观。