为什么C ++模板接受数组不比一个接受指针(bis)更专业?

时间:2018-01-24 18:50:42

标签: c++ templates language-lawyer partial-ordering

参考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 应该更专业。为什么不是这样呢?

1 个答案:

答案 0 :(得分:3)

早上好在评论中指出,原因是类型T*无法从char (&buf)[invented_N]类型中推断出来。

is_template_II_more_specialized中,根据[temp.deduct.call]/2.1应用额外的数组到指针转换:

  

如果P不是参考类型:

     
      
  • 如果A是数组类型,则使用数组到指针标准转换生成的指针类型代替A进行类型推导;否则,

  •   
  • ...

  •   

此规则仅适用于从函数调用中强制推导模板参数 。对于在部分排序期间推断模板参数,不存在此类转换。

在[temp.deduct.partial] / 567中描述了可以在部分排序期间应用的转化。