Jump to content
  • Advertisement
Sign in to follow this  
deathkrush

How to do this using templates in C++

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

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by _goat
Now, 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 Bregma
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.


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

Share this post


Link to post
Share on other sites
Quote:
Original post by _goat
I 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 this post


Link to post
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 this post


Link to post
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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!