I have a class which stores a scalar along with associated physical dimension exponents:
template <int L, int M, int T, int C, int K, int S, int I>
class Dimension<L, M, T, C, K, S, I>
{
...
}
I'd like to build a vector like class (Vec), with static storage, which stores an array of these objects. I would presume the Vec class template would look something like:
template <Dimension<L, M, T, C, K, S, I> D, size_t N>
class Vec
{
...
}
But this causes an error as the template parameter D
depends on template parameters (L
, M
, T
, C
, K
, S
, I
). I have tried a couple of things by brute force but I'm just guessing and would prefer to be shown the correct method by someone with expertise in the matter.
I have seen examples where template<class>
is inserted into the template arguments, but I don't quite understand what it achieves or even if it's actually applicable. Thanks very much for your help.
Note that I am aware that these class examples have been implemented before, probably in better ways.
Edit: Fixed a typo and changed name of Vec class.
If I understand correctly, you need template template
arguments.
Anyway, first of all remember to use the word struct
(or class
) for Dimension
template <int L, int M, int T, int C, int K, int S, int I>
struct Dimension
{ };
Second, you can declare a type vect
(please, not vector
, that can clash with the standard std::vector
) as follows
template <typename, std::size_t>
struct vect;
as receiving a type and an unsigned integer.
Then you can implement a partial specialization (with std::cout
exaple for the template integer values) as follows
template <template <int, int, int, int, int, int, int> class Dim,
int L, int M, int T, int C, int K, int S, int I, std::size_t N>
struct vect<Dim<L, M, T, C, K, S, I>, N>
{
vect ()
{ std::cout << " - L: " << L << " - M: " << M << " - T: " << T
<< " - C: " << C << " - K: " << K << " - S: " << S
<< " - I: " << I << " - N: " << N << std::endl; }
};
You can use this vect
as follows
vect<Dimension<2, 3, 5, 7, 11, 13, 17>, 42> v;
This works with C++98 also.
If you can use C++11 or newer, you can use variadic arguments so the vect
specialization can be simplified (a little) as follows
template <template <int...> class Dim,
int L, int M, int T, int C, int K, int S, int I, std::size_t N>
struct vect<Dim<L, M, T, C, K, S, I>, N>
{ /* ... */ };
or, using variadic arguments, a little more
template <template <int...> class Dim, int ... Is, std::size_t N>
struct vect<Dim<Is...>, N>
{ /* ... */ };
but, in this case, it's a little more complicated to use the single Is...
values.
But, if you can use at least C++11, I strongly suggest (following the example of Miles Budnek) the use of std::array
.