理解可变参数模板函数

understanding variadic template function

我是可变参数模板的新手,最近才发现它。我想我还没有完全理解它在后台是如何工作的。我试图写一个可变参数函数 min 其中 returns 参数的最小值。

代码如下:

#include <iostream>

template<typename T>
T min(T v) {
    std::cout << "Base func:     " << __PRETTY_FUNCTION__ << "\n";
    return v;
}

template<typename T, typename... Args>
T min(T first, Args... args) {
    std::cout << "Variadic func: " << __PRETTY_FUNCTION__ << "\n";
    return first < min(args...) ? first : min(args...);
}

int main(){

    std::cout << min(3,2,1,0) << std::endl;

    return 0;
}

我使用 __PRETTY_FUNCTION__ 获取函数实例化的更多细节,这里是输出:

Variadic func: T min(T, Args ...) [with T = int; Args = {int, int, int}]
Variadic func: T min(T, Args ...) [with T = int; Args = {int, int}]
Variadic func: T min(T, Args ...) [with T = int; Args = {int}]
Base func:     T min(T) [with T = int]
Base func:     T min(T) [with T = int]
Variadic func: T min(T, Args ...) [with T = int; Args = {int}]
Base func:     T min(T) [with T = int]
Base func:     T min(T) [with T = int]
Variadic func: T min(T, Args ...) [with T = int; Args = {int, int}]
Variadic func: T min(T, Args ...) [with T = int; Args = {int}]
Base func:     T min(T) [with T = int]
Base func:     T min(T) [with T = int]
Variadic func: T min(T, Args ...) [with T = int; Args = {int}]
Base func:     T min(T) [with T = int]
Base func:     T min(T) [with T = int]
0

代码 returns 是正确的输出,但我仍然不清楚函数是如何被调用的。是否所有论点都相互比较?例如。 3 将与 2,1,0 进行比较,2 将与 1,0 进行比较,而 1 将与 0 进行比较?如果有人能对到底发生了什么给出可靠的推理,那就太好了?

谢谢

调用层次如下。可变参数函数调用 "one less" 函数两次,因为 first < min(args...) ? first : min(args...); 调用它一次是为了将它与 first(标记为 // compare)进行比较,如果比较结果是 [=14,则会调用第二次=](标有// value)。

min(3,2,1,0) // compare
  -> min(2,1,0) // compare
    -> min(1,0) // compare
      ->min(0) // compare
      ->min(0) // value
    -> min(1,0) // value
      ->min(0) // compare
      ->min(0) // value
  -> min(2,1,0) // value
    -> min(1,0) // compare
      ->min(0) // compare
      ->min(0) // value
    -> min(1,0) // value
      ->min(0) // compare
      ->min(0) // value

我希望这能让您更易读。

如果展开模板调用并通过缓存递归值的结果来修复双递归,它应该如下所示

这不是c++,c++是问题中的模板代码,这只是传递3个args的手工调试

min (a, b, c)
  First = a;
  Tailmin = min (b, c);
  if (first < Tailmin)
     return first;
  return Tailmin;

min (b, c)
  First = b;
  Tailmin = min (c);
  if (first < Tailmin)
     return first;
  return Tailmin;

min (c)
// base stops recursion
   return c