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

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

引用this question ,它确实具有相同的标题,但我在标准中找到了答案。我继续深入研究这个主题,并最终找到了一个示例代码,该答案不适用。

让我们考虑这段代码:

template<class T> void func(T* buf);           //template I
template<size_t N> void func(char (&buf) [N]); //template II

void g(char (&buf)[3])
   {
   func(buf) //Error: ambiguous function call (Clang, GCC, ICC, MSVC)
   }

根据[temp.func.order]中的偏序规则和 [temp.deduct.partial] , template II 应该比 template I 更专业,如果通过执行这段代码来解释这个规则:

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
  }

因此,根据这种解释,模板 II 应该更专业。为什么不是这样?

最佳答案

作为 n.m.在评论中指出,原因是类型 T* 不能从类型 char (&buf)[invented_N] 推导出来。

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

If P is not a reference type:

  • If A is an array type, the pointer type produced by the array-to-pointer standard conversion is used in place of A for type deduction; otherwise,

  • ...

此规则仅适用于从函数调用 推导模板参数。对于在部分排序期间推导模板参数,没有应用此类转换。

可以在部分排序期间应用的转换在 [temp.deduct.partial]/5 中描述。 , 6 , 7 .

关于c++ - 为什么 C++ 模板接受数组并不比一个接受指针 (bis) 更专业?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48429659/

相关文章:

c++ - 这个尾随返回类型为 `this` 的函数指针是否合法?

c++ - 未解析的外部符号,即使我认为我链接正确(MSVC)

c++ - 转发引用、引用限定符和模板成员函数

c++ - 不可复制类数据成员的统一初始化导致gcc错误

c++ - vector::erase 会减少 vector::capacity 吗?

ruby-on-rails-3 - 在 Rails 模板的末尾显示一条消息

c++ - 重载函数声明的顺序在 C++ 中重要吗?

php - 如何将 C++ 应用程序集成到 PHP 网站中?

c++ - 需要 C++ 中非常通用的 argmax 函数

C++ typedef typename 类名::模板