参考this question,其确实具有相同的标题,但我在标准中找到了答案。我继续挖掘这个主题,最后找出一个不适用这个答案的示例代码。
让我们考虑一下这段代码:
template <class T> void func1(T* buf) {}
template <std::size_t N> void func2(char (&buf)[N]) {}
struct invented_T{};
constexpr std::size_t invented_N=42;
void is_template_I_more_specialized(invented_T* buf)
{
func2(buf);
//DO NOT COMPILE
// => template I is not more specialized than func2
}
void is_template_II_more_specialized(char (&buf)[invented_N])
{
func1(buf);
//DO COMPILE
// => template II is more specialized than func1
}
根据[temp.func.order]和[temp.deduct.partial]中的偏序排序规则,如果解释此规则,模板II 应比模板I 更专业化通过执行这段代码:
{{1}}
所以根据这种解释,模板II 应该更专业。为什么不是这样呢?
答案 0 :(得分:3)
早上好在评论中指出,原因是类型T*
无法从char (&buf)[invented_N]
类型中推断出来。
在is_template_II_more_specialized
中,根据[temp.deduct.call]/2.1应用额外的数组到指针转换:
如果P不是参考类型:
如果A是数组类型,则使用数组到指针标准转换生成的指针类型代替A进行类型推导;否则,
...
此规则仅适用于从函数调用中强制推导模板参数 。对于在部分排序期间推断模板参数,不存在此类转换。