I am writing a library that uses variadic-templated functions, like so:
template<typename ... T>
void func(T ... args) {
// ...
}
I need to ensure code is generated for this function (i.e. explicit instantiation) for certain types, like so:
template class func<int>;
template class func<int, int>;
template class func<int, int, int>;
// ...
where the max number of int
arguments is a non-const maxArgs()
(I am unable to change this as it is an external function). I have tried the following:
template<typename ... T>
void f(size_t max, T ... args) { // Generates "infinitely"
if (sizeof...(T) < max) {
func(args...);
f(max, args..., 0);
}
}
int main(int argc, char** argv) {
f(maxArgs(), 0);
// ...
return 0;
}
However the compiler doesn't have a proper base-case to the function generation recursion, so it fails to compile. I've also tried using non-type templates like so (using some code from here):
template<int ...> struct seq { };
template<int N, int ... Ns> struct gens : gens<N-1, N-1, Ns...> { };
template<int ... Ns> struct gens<0, Ns...> { typedef seq<Ns...> type; };
std::vector<int> params;
template<int ... Ns>
void f(seq<Ns...>) {
test(std::get<Ns>(params)...);
}
void instantiate(size_t max) {
for (int i = 1; i < max; ++i) {
for (int j = 0; j < i; ++j) {
params.push_back(0);
}
f(typename gens<i>::type()); // Fails to compile -- i is not const
params.clear();
}
}
int main(int argc, char** argv) {
instantiate(maxArgs());
}
but this requires a const value, so it fails to compile as well. Is there any way to do this properly having no knowledge of the return value of maxArgs()
?