The C++17 standard mentions a peculiar variadic function template that
- takes no normal function arguments but, instead,
- takes nontype template arguments,
like f<200, 50, 6>() == 256.
I thought, that's odd, let me see if I can code that myself. My code was elegant. My elegant code however would not compile, so after two fruitless hours I wrote this ugly code:
#include <iostream>
namespace {
template<int A> constexpr int f() {return A;}
template<int A, int B, int... C> constexpr int f() {
if (sizeof...(C)) return A + f<B, C...>();
else return A + B;
}
}
int main() {
int n = f<200, 50, 6>();
std::cout << n << "\n";
return 0;
}
This ugly code worked, and it was fun because it incidentally taught me sizeof...(). It cannot be right, though, can it?
Every time I try something simpler, the compiler balks, complaining about name-lookup conflicts or template redefinitions or something else of the kind.
My concept feels wrong. I suspect that I have missed the point. What point have I missed, please?
REFERENCE
For information, in the standard (draft here), the section that has provoked my question is sect. 5.13.8 (paragraphs 3 and 4). However, as far as I know, the provocation was incidental. My question is not about the standard as such. My question is about the proper, elegant use of variadics, rather.
NONCOMPILING EXAMPLE
If you want an example of my more elegant, noncompiling code, here is one:
namespace {
template<> constexpr int f() {return 0;}
template<int A, int... C> constexpr int f() {
return A + f<C...>();
}
}
After reading the compiler's error message, I understand why this particular code fails, so that is not my question. My question, rather, is
- how a variadic call like
f<200, 50, 6>()ought properly to have been implemented and - what concept I am consequently missing regarding C++ variadics.