Explicit instantiation for Variadic template functions

I'm writing a library that uses variadic-templating functions, for example:

template<typename ... T>
void func(T ... args) {
  // ...
}

      

I need to make sure that code is generated for this function (i.e. an explicit instance) for certain types:

template class func<int>;
template class func<int, int>;
template class func<int, int, int>;
// ...

      

where the maximum number of arguments int

is non-const maxArgs()

(I cannot change this as this is an external function). I've 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 does not have a proper baseline for function generation regeneration, so it does not compile. I've also tried using non-standard templates, for example (using the code 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 it requires a const value, so it won't compile either. Is there a way to do this correctly without knowing the return value maxArgs()

?

+3


source to share


2 answers


Since I know there is a maximum possible value maxArgs()

(namely 42), I came up with the following solution thanks to @JohnZwinck's suggestion.



#include <vector>

typedef void (*void_fnptr)();

std::vector<void_fnptr> table;

// Function that needs to be code-generated for certain number of int types
template<typename ... T>
void func(T ... args) {
  // ...
}

template<typename T>
void instantiate(T elem) {
  table.push_back((void_fnptr)func<T>);
}

template<typename T, typename ... Ts>
void instantiate(T first, Ts ... rest) {
  table.push_back((void_fnptr)func<T, Ts...>);
  instantiate(rest...);
}

int main(int argc, char** argv) {
  // 42 int arguments:
  instantiate(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
              0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
  // ...
  return 0;
}

      

0


source


No, you cannot generate compile-time templates that depend on a value known only at runtime. You will need to choose some kind of maximum value that is constant ahead of time (and sometimes not use all instances), or figure out a way to make maxArgs () a compile-time constant. Or compile your code on the fly when it's used!



Since you have more information than we do about this code, you might be wondering if this is really a variation pattern. This does not appear to be the case, given that the number of template arguments is determined at runtime. It might be better to write a solution that is fully defined at runtime, without the variational template stuff.

+1


source







All Articles