具有以下3个重载
template <class T> auto foo() { return 1; }
template <class T> int foo() { return 2; }
template <class T> T foo() { return 3; }
下列疾病形成了吗?
static_cast<int(*)()>(&foo<int>)();
Clang选择重载#2,而gcc无法编译(Demo)
除去过载#1时,双方都同意选择过载#2(Demo)。
删除#2重载时,gcc选择#1重载,而clang编译失败(Demo)
最佳答案
根据[over.over]/2,我们执行模板参数推导。这对于所有三个重载都将成功:在第一个重载中,请记住[temp.deduct.funcaddr]/2:
由于推论将成功(假设所有模板参数均已明确提供参数),因此将返回类型推导为int
。在第二种情况下,由于提供了参数,推导成功,而在第三种情况下,将推导T
。 †
继续paragraph 4,
根据[temp.deduct.partial]/3,功能模板的功能类型用于部分排序。我们可以立即看到,#1和#2的函数类型不包含任何参与推论的模板参数,因此,通过对核心问题[temp.deduct.partial]/4的分辨率引入的1391的添加,它们相应的P
不会用于确定排序。 @bogdan解释here为什么该分辨率有问题;最重要的是,排序只会对#1和#2产生歧义。
即,根据当前(可能是有缺陷的)措辞,在所有情况下转换都是不正确的。如果部分非固定/推论参数的部分排序是固定的,
†[temp.deduct.type]/8元素9(
T()
),以防您感到好奇。