Here is a short program to print tuples using code adapted from answers from Johannes Schaub - litb and Luc Danton.
#include
#include
template
struct seq { };
template
struct gens : gens { };
template
struct gens<0, S...> {
typedef seq type;
};
template
void print(const std::tuple & tup, seq s) {
int res[] = { (std::cout << std::get(tup) << " ", 0)... };
std::cout << std::endl;
}
int main() {
std::tuple tup(1.5, 100, 'c');
print(tup, gens::value >::type());
return 0;
}
The second argument of print will always be always be gens, where N is the size of the tuple. I am trying to eschew the second argument to print by providing a default argument:
template
void print(const std::tuple & tup, seq s = gens::value >::type()) {
int res[] = { (std::cout << std::get(tup) << " ", 0)... };
std::cout << std::endl;
}
However, the result is a compiler error:
tmp5.cpp: In function ‘void print(const std::tuple<_Elements ...>&, seq) [with int ...S = {}; T = {double, int, char}]’:
tmp5.cpp:23:12: error: incomplete type ‘std::tuple_size&>’ used in nested name specifier
Do you know of any way to provide S... without the second argument to functions like print?
Answer
No, there is not.
As a matter of fact, this issue is not restricted to variadic template, it occurs for all template functions: the template type of an argument cannot be deduced from its default value.
template
void func(T = 0) {} // expected-note {candidate template ignored:\
couldn't infer template argument 'T'}
int main() {
func(); // expected-error {no matching function for call to 'func'}
}
You need to switch gears.
The easiest way to do so would be to provide an overload that would be tasked with passing the second argument. After all, default arguments are just syntactic sugar to avoid writing a forwarding function.
No comments:
Post a Comment