You cannot store or generate a type from a class template
template <int... N>
class FooImpl;
with run-time integers as template arguments. However, if the following might also fit your actual problem, you could store and then look up a pointer-to-function
template <int... N>
R FooFun(A...);
given run-time integers as template arguments, assuming the function signature R(A...)
is the same for all template arguments. Note that A...
is not a pack of template parameters here; it's just a placeholder for the types of your own concrete function parameters, e.g. FooFun(int, int)
.
It seems to me that this formulation indeed fits your problem because you have a factory function with no input parameters that returns a pointer to object FooImpl<N...>
always seen as Foo*
, so in your case FooFun
would look like
template <int... N>
Foo* FooFun();
A general solution for this kind of conversion is based on a look-up table of pointers-to-function and is given in this answer of my previous question adapting a non-constexpr integral value to a non-type template parameter (which by the way works very smoothly now and I'm very happy with it - my actual implementation is here).
The difference in your case is that you need a multi-dimensional look-up table. I suggest that you first define a function "dispatcher" with only one integer template argument
template <int OFFSET>
R FooDispatch(A...);
which represents the linear offset in the multi-dimensional table. In this case the previous solution applies directly to FooDispatch
. Then, you have to convert OFFSET
to a set of multi-dimensional indices N...
, at compile time. For this, you would also need to know the dimensions of the table, or better its strides, again at compile time. Having deduced arguments N...
, FooDispatch
can now call FooFun<N...>(...)
.
To be more precise, the logic of this offset-to-index conversion is exactly as in Matlab's function ind2sub, only it's a compile-time operation. This would need some work, so if you like this approach and need help in this last step, I'd be happy to assist. In this case, I think you'd better post a new question with the sub-problem appropriately formulated.
All the above imply that the number of dimensions is also known at compile time, so eventually a function of the form
Foo* getFoo(int arr[N]);
would be fine as an interface, but
Foo* getFoo(int* pint, int size);
does not make much sense; you could only make a run-time check in the latter case, and maybe throw an exception if dimensions do not agree.
Finally, note that using out-of-range indices at run-time would have the same effect as using out-of-range indices in an ordinary C array.