这已经是一个很好的答案了,然而,当我试图将参数作为typename(不知道确切的单词)做同样的事情时,它们传递了任意数量的参数作为参数,例如:
int sum=0;
int func()
{
return sum;
}
template <int first, int ... rest>
int func()
{
sum += first;
return func(rest...); //Error C2660 'func': function does not take 4 arguments
/*
return func<rest...>(); this also doesn't work: Error 'int func(void)': could not deduce template argument for 'first' and 'func': no matching overloaded function found
*/
}
int main()
{
cout << func<1,2,3,4,5>();
}
为什么这里有错误?有什么可能的解决办法吗?此外,我需要将参数作为类型名传递,而不是参数。
首先,<base"函数>也是需要是模板。
然后,为了区分两个模板,形参包模板需要接受至少两个模板实参。
最后,您可以不使用全局sum
变量,而是使用return
语句中的加法来解决这个问题。
把它们放在一起:
template <int first>
int func()
{
return first;
}
template <int first, int second, int ...rest>
int func()
{
return first + func<second, rest...>();
}
对于一个简单的用例,作为值的总和,有很多方法(如Some programmer dude和p Kramer的回答)。
我将向您展示递归解决方案的一种变体(一些程序员的答案),它在这种情况下不是特别有用,但在其他情况下可能有用(避免在基础函数与递归版本一致并相等时代码重复):而不是接收和管理最后一个值的基础情况版本,接收默认类型并且不做任何事情(在sum情况下返回零):
template <typename = void>
int func ()
{ return 0; }
,所以你可以这样写递归版本,不带second
template <int first, int ... rest>
int func ()
{ return first + func<rest...>(); }
关键在于递归调用:func<rest...>()
当...rest
模板包不为空时,递归调用func<rest...>()
调用递归func()
。
但是当...rest
模板包为空时,递归调用func<rest...>()
变成func<>()
,它不匹配递归func()
(至少需要一个模板整数值),但匹配(由于默认的void
类型)func<void>()
,因此地面func()
函数。
如果您想返回参数包的和,并且您可以接受稍微不同的语法,您可以使用c++ 17以后的折叠表达式或使用' If constexpr'构建递归
template<typename... args_t>
static constexpr auto sum(args_t&&... values)
{
return (values + ...);
}
// the sum is evaluated at compile time
static_assert(sum(1, 2, 3, 4) == 10ul);
// or like this without fold
template<int value, int... values>
constexpr int sum2()
{
if constexpr (sizeof...(values) > 0)
{
return value + sum2<values...>();
}
else
{
return value;
}
};
static_assert(sum2<1,2,3,4>() == 10);
出于好奇,这里是没有递归的版本:
// C++11
template<typename... Ts>
void dummy(Ts... t)
{
}
template<typename T>
T addValue(T& sum, T value)
{
sum += value;
return 0;
}
template<typename SumType, typename... Ts>
SumType sumVariadicArgs(Ts... t)
{
SumType sum = 0;
dummy(addValue(sum, t)...);
return sum;
}
int main()
{
int sum = sumVariadicArgs<int>(1, 2, 3);
double sum2 = sumVariadicArgs<double>(1.0, 2.0, 3.0);
return 0;
}