This is what I'm trying to do:
// 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;
}
It doesn't compile:
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’
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?
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;
}
http://ideone.com/yyg6y9:
#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.
Variadic function templates in C++. Variadic templates are template that take a variable number of arguments. Variadic function templates are functions which can take multiple number of arguments.
Douglas Gregor and Jaakko Järvi came up with this feature for C++. Variadic arguments are very similar to arrays in C++. We can easily iterate through the arguments, find the size (length) of the template, can access the values by an index, and can slice the templates too.
Variadic Functions. A function with variable number of… | by Chuan Zhang | The Startup | Medium A function with variable number of arguments is called a variadic function, and also known as variable argument function [1]. Due to its flexibility in size of the list of input arguments, it is very useful especially in system programming.
When using variadic templates you may end up in a situation, where you would like to know how many arguments are actually passed. Let’s say that you want to store them in a table. How big should it be? sizeof... () will tell you: template <typename... Args> void func (Args... args) { int argsTable [sizeof... (args)] = {args...};
Since c++20 you can use constraints to functions, instead of SFINAE.
template <typename... Ts>
requires (sizeof...(Ts) == 0)
void f(){}
template <typename T, typename... Ts>
void f() {
// do something with T
f<Ts...>();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With