首页 > 解决方案 > C++ 中的可变参数模板及其工作原理

问题描述

所以我试图了解可变参数模板是如何工作的,所以我有这个代码:

template <typename Res, typename Type>
void Sum(Res &result, Type &val)
{
    result += val;
}

template <typename Res, typename First, typename... Rest>
void Sum(Res &result, First val1, Rest... valN)
{
    result += val1;
    return Sum(result, valN...);
}

现在我的书说:

Sum()编译器实际上为适合调用的正确类型创建代码,递归地执行此操作,直到处理完所有参数。

现在我不明白这一点,我也尝试过调试,我看到第二个 Sum 函数块被每个 valN 值调用,然后在最后一个调用第一个Sum()函数,这对我没有任何意义。

我还了解到,要解压它们,我们需要在可变参数模板函数中使用函数调用,这是真的吗?

为什么我们必须解压它们,我不明白,我们不能直接在可变参数模板函数中访问它们吗?

提前致谢。

标签: c++templates

解决方案


我认为您可能会忽略一点,即当您在调试器中单步执行此操作时,您每次都会输入一个完全不同的函数。
(请注意,val1在“下一个”调用中不使用它,因此您每次都少传递一个参数。)

如果没有可变参数模板,您需要将它们拼写为单独的模板,但它是完全相同的:

template <typename Res, typename T>
void Sum(Res& result, T val)
{
    result += val;
}

template <typename Res, typename T1, typename T2>
void Sum(Res& result, T1 val1, T2 val2)
{
    result += val1;
    Sum(result, val2);
}

template <typename Res, typename T1, typename T2, typename T3>    
void Sum(Res& result, T1 val1, T2 val2, T3 val3)
{
    result += val1;
    Sum(result, val2, val3);
}

template <typename Res, typename T1, typename T2, typename T3, typename T4>        
void Sum(Res& result, T1 val1, T2 val2, T3 val3, T4 val4)
{
    result += val1;
    Sum(result, val2, val3, val4);
}

template <typename Res, typename T1, typename T2, typename T3, typename T5>    
void Sum(Res& result, T1 val1, T2 val2, T3 val3, T4 val4, T5 val5)
{
    ...

等等,你需要多少就多少。

可变参数模板使编译器“按需”生成所有这些,并避免您将它们全部写出来。

一种看待它的方法是常规函数模板(只有类型参数)生成具有相同数量参数的重载;可变参数模板还允许您生成具有不同数量参数的重载。

直接访问是不可能的,因为您不知道参数包中有多少元素,它们的类型是什么,而且它们没有名称。
如果你想访问一个特定的参数,你还需要让它显式。


推荐阅读