模板推导和参数包的显式提供类型

template deduction and explicitly supplied types for parameter packs

本文关键字:类型 参数      更新时间:2023-10-16

我将简化和缩短这个问题以方便回答。

本质是:

为什么编译和执行此代码

  # include <iostream>
  template <class A> class Goofy {};
  template <int N, template <class> class B, class A, int ... K, class ... Z>
  void f ( A a, B<A> b, Z ... z )
  {
   std::cout << "I'm executed" << std::endl;
  }
  int main()
  {
   Goofy<int> goofy;
   f<1, Goofy, int, 2, 3, 4>(2,goofy,1.3,'a',1.f);
   }

而以下不是?

  # include <iostream>
  template <class A> class Goofy {};
  template <int N, template <class> class B, class A, int ... K, class ... Z>
  void f ( A a, B<A> b, Z ... z )
  {
   std::cout << "I'm executed" << std::endl;
  }
  int main()
  {
   Goofy<int> goofy;
   f<1, Goofy, int, 2, 3, 4, double, char, float>(2,goofy,1.3,'a',1.f);
   }

唯一的区别是显式和一致的类型供应实例化包Z .

我不认为这会以编译错误告终,而且诊断告诉模板扣除/替换失败时,恕我直言,不需要扣除。

谁能向我解释一下?

我使用了编译器 GNU 7.3.1 和 clang 4.0.1,两者的行为相同,所以我担心我的推理中存在严重错误......但我找不到什么。

您的代码可以简化为:

template <int... N, class T>
auto foo(T) {};
auto test()
{
    foo<1, 2, 3>(4); // OK
    foo<1, 2, 3, int>(4); // ERROR
}

原因是可变参数是贪婪的。这就是为什么在明确陈述它们时它们需要排在最后的原因。

当你写foo<1, 2, 3>(4);

  • 1, 2, 3int... N匹配 -> N推导出1, 2, 3 ->确定
  • 然后从函数参数推导出T,即 4 int -> 确定

当你写foo<1, 2, 3, int>(4);

  • 1, 2, 3, intint... N -> 错误匹配