# How to do this using templates in C++

This topic is 4334 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I'm writing a Vector and Matrix library and the problem I stumbled upon is the fact that every Vector2, Vector3 and Vector4 needs to be defined as a separate class, even though the functions are all the same, they just use a different number of data members. I was just thinking that maybe there was a way to use templates, macros or inheritance to reuse some of that code. Is this possible using templates:
template <class T, int n>
class Vector
{
T x;
T y;
$if(n>=3) //just kidding, I WISH there was a keyword like that T z;$endif
$if(n==4) T w;$endif
};


I tried doing this, but partial template specialization requires that I redefine the class every time, so it's kind of pointless:
template <class T, int n>
class Vector
{
T data[n];
};

template <class T, int n>
class Vector<T, 2>
{
T data[n];
Vector(T _z, T _y);
};

template <class T, int n>
class Vector<T, 3>
{
T data[3];
Vector(T _x, T _y, T _z);
};


Did anybody have this issue, and if so, how did you solve it? Thanks.

##### Share on other sites
With me i had so many problems with C++ that i changed over to C# language. even though its almost the same thing but it is easier to use C#, you also should get alot less problems for your "Vector and Matrix library". i hope this will help.

##### Share on other sites
via explicit instantiation. A code generator could help the tedium, but there's no template magic I know of to get that working.

##### Share on other sites
I specialised the classes, using the little anonymous union/struct trick:

template <typename T> SVector<3, T>{	union	{		struct		{			T x, y, z;		};		T mElements[3];	};};

Now, since each specialisation has a member called mElements, I can make friend functions/operators of the unspecialised class without needing to rewrite them. In the above, Any SVector<3> has members x y and z, but SVector<253> won't (my SVector<2> specialisation has x and y, and my SVector<4> has x y z w). If that makes any sense. I can divulge source code if it helps.

##### Share on other sites
I would make two suggestions (although neither may be to your liking).

First, look at how the standard library does it. Those guys are pretty clever. Examine, for instance, the std::valarray class.

Second, I would suggest (and I don't do this lightly) using inheritance. Yes, you'll have to duplicate some code, but most functions can be moved into a templated base class.

template<typename T, int n>  class VectorBase  {  public:    VectorBase operator+=(const VectorBase& rhs)    {      for (int i = 0; i < n; ++i)      {        m_data += rhs.m_data;      }      return *this;    }    // other operations...  protected:    T m_data[n];  };template<typename T>  class Vector2: public VectorBase<T, 2>  {  public:    Vector2(T x, T y) { i/* ... */ }  };template<typename T>  class Vector3: public VectorBase<T, 3>  {  public:    Vector3(T x, T y, T z)    { this->m_data[0] = x; this->m_data[1] = y; this->m_data[2] = z; }  };main(){  Vector3<int> v0(0, 0, 0);  Vector3<int> v1(1, 1, 1);  v1 += v0;}

##### Share on other sites
My vector class is similar. It is parametised by the type of the elements and the number of elements. I had to specialise the vector for sizes 2, 3 and 4 to define the x, y, z and w members and define an operator[]. Then all other operators and functions were made non-member non-friends, and operated on vectors of all sizes generically by using the size template parameter and looping through all elements via operator[]. These loops are optimized out by the compiler.

##### Share on other sites
Quote:
 Original post by _goatNow, since each specialisation has a member called mElements, I can make friend functions/operators of the unspecialised class without needing to rewrite them.

That sounds like a great idea. Can you provide an example how to reuse code using friend functions? So far my impression of partial specialization was that for each specialized template I have to rewrite everything.

Quote:
 Original post by BregmaFirst, look at how the standard library does it. Those guys are pretty clever. Examine, for instance, the std::valarray class.Second, I would suggest (and I don't do this lightly) using inheritance. Yes, you'll have to duplicate some code, but most functions can be moved into a templated base class.

Templates and inheritance... that's pretty clever, I'll try it. Thanks.

##### Share on other sites
Quote:
 Original post by _goatI specialised the classes, using the little anonymous union/struct trick:

Could you please post a little more on this - i'm not sure i fully understand it, but it sounds very interesting.

Note: I need to see the some member functions, as well as some operators.

Thenk you.

##### Share on other sites
A better solution than using an anonymous union was posted a while back. Search for "A slick trick in C++".

##### Share on other sites
Unless you have severe memory constraints It would be way easier to just use a vec4 all the time and if you don’t need the extra parameters just set them to 0

• 23
• 10
• 19
• 15
• 14