In trying to call a variadic template, I was getting errors. This question has now been split into the error, and the deeper goal which is in Is it possible to build a const array at compile time using a c++ variadic template?
To test the variadic template in isolation, I tried to just print out the values. So I'm obviously messing up the template somehow:
template<typename T, typename ...Args>
void test(T first, Args... args) {
cout << sizeof(first) << '\n';
test(args...);
}
int main() {
test(123_u32, 1234_u64, 1.23_f32, 1.23456_f64);
}
The error is:
error: no matching function for call to ‘test()’ test(args...);
What I don't understand is, this was taken from Eli Bendersky's blog post, and this works:
template<typename T, typename... Args>
T adder(T first, Args... args) {
return first + adder(args...);
}
You must remember that templates are templates.
template<typename T, typename ...Args>
void test(T first, Args... args) {
cout << sizeof(first) << '\n';
test(args...);
}
int main() {
test(123_u32, 1234_u64, 1.23_f32, 1.23456_f64);
}
This will expand to
void test(uint32_t first, uint64_t arg1, float32_t arg2, float64_t arg3) {
cout << sizeof(first) << '\n';
test(arg1, arg2, arg3);
}
void test(uint64_t first, float32_t arg1, float64_t arg2) {
cout << sizeof(first) << '\n';
test(arg1, arg2);
}
void test(float32_t first, float64_t arg1) {
cout << sizeof(first) << '\n';
test(arg1);
}
void test(float64_t first) {
cout << sizeof(first) << '\n';
test(); //ERROR
}
int main() {
test(123_u32, 1234_u64, 1.23_f32, 1.23456_f64);
}
To tackle this you can create a specialized version that accepts exactly one arguments, that doesn't call test()
without arguments.
template<typename T>
void test(T first) {
cout << sizeof(first) << '\n';
}
The mentioned blog post, does exactly the same.
Edit:
As pointed out by @Jarod42 with C++17 and up you don't need to write recursive templates but can directly use the parameter pack using fold expressions:
template<typename ...Ts>
void test(Ts... args)
{
((std::cout << sizeof(first) << '\n'), ...);
}