值作为可变参数模板的参数
Value as arguments for variadic template
我正在尝试使用可变参数模板创建求和函数。
#include <iostream>
int sum() {
return 0;
}
template <int first, int ...Rest>
int sum() {
return first + sum<Rest...>();
}
int main() {
sum<1, 2, 3>();
}
但是我得到了这样的错误:
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...>();
所以我改变了
int sum { return 0; }
到
template<int first>
int sum { return first; }
但我遇到了另一个错误:
test.cc:11:31: error: call of overloaded 'sum<3>()' is ambiguous
return first + sum<Rest...>();
~~~~~~~~~~~~^~
我该怎么办?
在 C++17 中,您可能会这样做:
template <int first, int ...Rest>
int sum() {
return (first + ... + Rest);
}
替代方法是使用 class 和专业化:
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; }
};
你的问题是当 Rest
为空时 sum<Rest...>()
不会调用 int sum()
因为那个函数不是模板。
当您将其更改为
template<int first>
int sum { return first; }
那么问题就变成了 template<int first> int sum
和 template <int first, int ...Rest> int sum()
与 Rest
为空解析为相同的函数。这里没有关于平分的规则,所以你会得到一个编译器错误。
解决此问题的旧方法是向可变参数模板添加另一个模板参数,从而为您提供一组重载
template <int first>
int sum() {
return 0;
}
template <int first, int second, int ...Rest>
int sum() {
return first + sum<second, Rest...>();
}
一旦 Rest
为空,唯一可行的调用函数是 template <int first> int sum()
既然我们有了折叠表达式,就不再需要它了,您可以使用
template <int... Vals>
int sum() {
static_assert(sizeof...(Vals) > 0, "You must provide at least one template parameter");
return (... + Vals);
}
我正在尝试使用可变参数模板创建求和函数。
#include <iostream>
int sum() {
return 0;
}
template <int first, int ...Rest>
int sum() {
return first + sum<Rest...>();
}
int main() {
sum<1, 2, 3>();
}
但是我得到了这样的错误:
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...>();
所以我改变了
int sum { return 0; }
到
template<int first>
int sum { return first; }
但我遇到了另一个错误:
test.cc:11:31: error: call of overloaded 'sum<3>()' is ambiguous
return first + sum<Rest...>();
~~~~~~~~~~~~^~
我该怎么办?
在 C++17 中,您可能会这样做:
template <int first, int ...Rest>
int sum() {
return (first + ... + Rest);
}
替代方法是使用 class 和专业化:
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; }
};
你的问题是当 Rest
为空时 sum<Rest...>()
不会调用 int sum()
因为那个函数不是模板。
当您将其更改为
template<int first>
int sum { return first; }
那么问题就变成了 template<int first> int sum
和 template <int first, int ...Rest> int sum()
与 Rest
为空解析为相同的函数。这里没有关于平分的规则,所以你会得到一个编译器错误。
解决此问题的旧方法是向可变参数模板添加另一个模板参数,从而为您提供一组重载
template <int first>
int sum() {
return 0;
}
template <int first, int second, int ...Rest>
int sum() {
return first + sum<second, Rest...>();
}
一旦 Rest
为空,唯一可行的调用函数是 template <int first> int sum()
既然我们有了折叠表达式,就不再需要它了,您可以使用
template <int... Vals>
int sum() {
static_assert(sizeof...(Vals) > 0, "You must provide at least one template parameter");
return (... + Vals);
}