我是可变参数模板的新手,最近遇到了它。我想我还没有完全理解它在后台如何运作。我试着写一个可变函数 min ,它返回最小的参数。
以下是代码:
#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
代码返回正确的输出,但我仍然模糊调用函数的方式。是否所有论据都相互比较?例如。 3
将与2,1,0
进行比较,2
将与1,0
进行比较,1
将与0
进行比较?如果有人可以对确切的事情给出一个可靠的推理,那将会很棒吗?
由于
答案 0 :(得分:3)
调用层次结构如下。可变函数调用“少一个”函数两次,因为first < min(args...) ? first : min(args...);
调用它一次以将其与first
(标有// compare
)进行比较,如果比较为{{1}则第二次调用false
}(标有// 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
我希望这会让你更具可读性。
答案 1 :(得分:1)
如果您展开模板调用并通过缓存递归值的结果来修复双递归,它应该看起来像这样
这并不意味着是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