简体   繁体   English

作为可变参数模板参数的值

[英]Value as arguments for variadic template

I'm trying to make a sum function using variadic template.我正在尝试使用可变参数模板创建 sum 函数。

#include <iostream>

int sum() {
   return 0;
}

template <int first, int ...Rest>
int sum() {
   return first + sum<Rest...>();
}

int main() {
   sum<1, 2, 3>();
}

But I got an error like this:但我收到了这样的错误:

test.cc: In instantiation of 'int sum() [with int first = 3; int ...Rest = {}]':  
test.cc:10:31:   recursively required from 'int sum() [with int first = 2; int ...Rest = {3}]'
test.cc:10:31:   required from 'int sum() [with int first = 1; int ...Rest = {2, 3}]'
test.cc:14:17:   required from here
test.cc:10:31: error: no matching function for call to 'sum<>()'
    return first + sum<Rest...>();
                   ~~~~~~~~~~~~^~
test.cc:9:5: note: candidate: 'template<int first, int ...Rest> int sum()'        
 int sum() {
     ^~~
test.cc:9:5: note:   template argument deduction/substitution failed:
test.cc:10:31: note:   couldn't deduce template parameter 'first'
    return first + sum<Rest...>();

so I changed所以我改变了

int sum { return 0; } 

to

template<int first>
int sum { return first; }

but I got an another error:但我遇到了另一个错误:

test.cc:11:31: error: call of overloaded 'sum<3>()' is ambiguous
    return first + sum<Rest...>();
                   ~~~~~~~~~~~~^~

What should I do?我该怎么办?

Your issue here is that sum<Rest...>() when Rest is empty won't call int sum() because that function is not a template.您的问题是当Rest为空时sum<Rest...>()不会调用int sum()因为该函数不是模板。

When you change it to当你把它改成

template<int first>
int sum { return first; }

then the issue becomes that template<int first> int sum and template <int first, int ...Rest> int sum() with Rest being empty resolve to being the same function.那么问题就变成了template<int first> int sumtemplate <int first, int ...Rest> int sum()Rest为空解析为相同的函数。 There are no rules about a tie break here so you get a compiler error.这里没有关于平局的规则,所以你会得到一个编译器错误。

The old way to fix this was to just add another template parameter to the variadic template giving you an overload set of解决这个问题的旧方法是向可变参数模板添加另一个模板参数,为您提供一个重载集

template <int first>
int sum() {
   return 0;
}

template <int first, int second, int ...Rest>
int sum() {
   return first + sum<second, Rest...>();
}

and with that once Rest is empty the only viable function to call is template <int first> int sum()一旦Rest为空,唯一可行的调用函数是template <int first> int sum()

Now that we have fold expressions this isn't needed anymore and you can just use现在我们有了折叠表达式,这不再需要了,您可以使用

template <int... Vals>
int sum() {
   static_assert(sizeof...(Vals) > 0, "You must provide at least one template parameter");
   return (... + Vals);
}

In C++17, you might do:在 C++17 中,你可以这样做:

template <int first, int ...Rest>
int sum() {
   return (first + ... + Rest);
}

Alternative would be to use class and specialization:替代方法是使用类和专业化:

template <int N, int Is...>
struct sum
{
    int operator () () const { return N + sum<Is...>{}(); }
};

template <int N>
struct sum<N>
{
    int operator () () const { return N; }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM