没有形式参数的可变函数模板 [英] variadic function template without formal parameters
问题描述
这是我想要做的:
// base case
void f() {}
template <typename T, typename... Ts>
void f() {
// do something with T
f<Ts...>();
}
int main() {
f<int, float, char>();
return 0;
}
它不编译:
prog.cpp: In instantiation of ‘void f() [with T = char; Ts = {}]’:
prog.cpp:6:5: recursively required from ‘void f() [with T = float; Ts = {char}]’
prog.cpp:6:5: required from ‘void f() [with T = int; Ts = {float, char}]’
prog.cpp:10:25: required from here
prog.cpp:6:5: error: no matching function for call to ‘f()’
prog.cpp:6:5: note: candidate is:
prog.cpp:4:6: note: template<class T, class ... Ts> void f()
prog.cpp:4:6: note: template argument deduction/substitution failed:
prog.cpp:6:5: note: couldn't deduce template parameter ‘T’
这个线程显示了一种解决这个问题的方法,但基本案例必须是一个模板。我真的不喜欢它,因为根据我的理解,我将不得不重复代码与T一起工作。有一种方法可以避免这样吗?
This thread shows a way to fix this, but the base case has to be a template. I don't really like it, because as far as I understand I will have to duplicate code that works with T. Is there a way to avoid that?
到目前为止我想出了两个解决方案( http://ideone.com/nPqU0l ):
So far I came up with two solutions (http://ideone.com/nPqU0l):
template <typename...> struct types_helper {};
// base case
void f(types_helper<>) {}
template <typename T, typename... Ts>
void f(types_helper<T, Ts...>) {
// do something with T
f(types_helper<Ts...>());
}
int main() {
f(types_helper<int, float, char>());
return 0;
}
#include <type_traits>
struct end_of_list;
template <typename T>
void f() {
static_assert(std::is_same<T, end_of_list>::value, "error");
}
template <typename T1, typename T2, typename... Ts>
void f() {
// do something with T
f<T2, Ts...>();
}
int main() {
f<int, float, char, end_of_list>();
return 0;
}
我不知道有没有更好的方法。
I wonder if there is a better way to do this.
推荐答案
另一种方法是将非模板函数 f
转换为可变模板函数接受零个或多个模板参数(另一个 f
需要一个或多个模板参数)。然后为了避免歧义,当参数数量不为零时,SFINAE去掉这个模板函数。好了,代码比1000个字更好:
Another way is turning the non-template function f
into a variadic template function which accepts zero or more template arguments (the other f
requires one or more template arguments). Then to avoid ambiguity, SFINAE away this template function when the number of arguments is not zero. Well, a code is better than 1000 words:
#include <type_traits>
template <typename... Ts>
typename std::enable_if<sizeof...(Ts) == 0>::type f() {
}
template <typename T, typename... Ts>
void f() {
// do something with T
f<Ts...>();
}
这篇关于没有形式参数的可变函数模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!