Sign in to follow this  

templatized matrix system with inheritance

This topic is 3583 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 attempting to represent matrices in a fast and scalable way. I haven't done too much programming with templates and inheritance, but I've been running into some trouble, maybe someone can take a quick look at this setup. In four separate files I have, highly abbreviated. the base matrix class. in BaseMatrix.h template<class Type, int rows, int cols> class Matrix{ /* stuff */ }; then in ColumnMatrix.h #define Vector2f ColumnMatrix<float, 2>//, etc... 5 more of these template<class Type, int size> class ColumnMatrix : public Matrix<Type, size, 1>{ /* stuff */ } also there is SquareMatrix.h #define Matrix2f SquareMatrix<float, 2>//, etc... 5 more of these template<class Type, int size> class SquareMatrix : public Matrix<Type, size, size>{ /* stuff */ } and finally Transformation.h #define Transformationf Transformation<float> #define Transformationd Transformation<double> template<class Type> class Transformation : public SquareMatrix<Type, 4>{ /* stuff */ } now when I usee these in other places, say using a column matrix, or vector3f for a color, and passing that in as a parameter, it has a type mismatch, as follows: error: no matching function for call to ‘BASE::GRAPHICS::Graphics::Color(BASE::MATH::Matrix<float, 3, 1>, float)’ candidates are: void BASE::GRAPHICS::Graphics::Color(BASE::MATH::ColumnMatrix<float, 3>) Any ideas on how to get rid of this ambiguity.

Share this post


Link to post
Share on other sites
Nyarlath, sorry, I posted the wrong candidate, there are many for that function, including one that accepts a vector3f and a float.

Mawww, I had them in as typedefs, but then I read typedef's for templates are bad.

Notice the main problem is, when I try to pass one of my derived types, c++ passes it in as the base class with the proper template params, however, then it doesn't have the derived functionality. I want to pass in a columnMatrix which is a Matrix<Type, size, 1> plus some higher level functionality for vectors.

Share this post


Link to post
Share on other sites
If you're looking for a fast, easy to use matrix library, there's always CML It's open source under the boost software license. You can always use it for inspiration, or even better, use it, and improve upon it :-). I've yet to use it myself honestly, but it looks really good and I'll be using it the next chance I get. I'm not much of a template wizard myself otherwise i'd contribute some code too.

Share this post


Link to post
Share on other sites
With template inheritance, do I also need to remake all arithmatic assignment operators for each derived class. For instance I know I have to remake the assignment operator for each derived class (operator=), but what about (oeprator+=)?

Share this post


Link to post
Share on other sites
Quote:
Original post by Enalis
Mawww, I had them in as typedefs, but then I read typedef's for templates are bad.
That makes no sense to me. I don't suppose you're able to remember where you read that?
However let me make this clear: "#defines instead of typedefs are bad".
There I've said it.

Share this post


Link to post
Share on other sites
Adam_42, that worked well thanks, but of course there's plenty more problems as described. It's seeming now that c++ might not be so accomodating for using templates and making things as flexible as I want right now. Should I just switch to a non-templatized system for now?

Share this post


Link to post
Share on other sites
Quote:
Original post by Enalis
I had them in as typedefs, but then I read typedef's for templates are bad.


Trying to make the typedef itself templated doesn't work (the best you can do is have a typedef as a member of a templated class, and then select it from an instantiation of the class, specifying it as a 'typename' since you now have a dependent name). But typedeffing a specific instantiation of a class is perfectly kosher.

Quote:
Adam_42, that worked well thanks, but of course there's plenty more problems as described. It's seeming now that c++ might not be so accomodating for using templates and making things as flexible as I want right now. Should I just switch to a non-templatized system for now?


You might consider that boost::array can do a lot of the work for you.

But I think the main problem is that you are trying to derive "column matrix" and "square matrix" classes. For the concept of "class ColumnMatrix : public Matrix<Type, size, 1>" to make sense, given that the base Matrix makes sense to instantiate, there has to be a reason why I would want to instantiate a ColumnMatrix specifically, and a reason why I would want to just instantiate a 1xN matrix in some other situation. I could see making a Vector class, but it wouldn't be related by inheritance. Instead, the Matrix would be composed of (either row or column) Vectors.

Almost certainly, what you really want to do is write free functions that work on special cases:


template <typename T, int size>
T trace(const Matrix<T, size, size>& m);

template <typename T, int length>
Matrix<T, length, 1> Row(const Vector<T, length>& r);

template <typename T, int length>
Matrix<T, 1, length> Column(const Vector<T, length>& r);

template <typename T, int length>
// I'll implement this one just for an example
T dot(const Vector<T, length>& a, const Vector<T, length>& b) {
return (Row(a) * Column(b))[0][0];
}

template <typename T>
T cross(const Vector<T, 3>& a, const Vector<T, 3>& b);

Share this post


Link to post
Share on other sites
Quote:
Original post by Enalis
Mawww, I had them in as typedefs, but then I read typedef's for templates are bad.
Hm, what was the reference? Sounds like either it's a poor reference, or whatever the message was supposed to be was 'lost in translation', so to speak.

Anyway, typedef's are not only appropriate, but recommended (arguably even necessary) when working with heavily templated code.

[Oops, looks like maybe you were referring to templated typedefs...]

Share this post


Link to post
Share on other sites
Man, I was hoping to have a nice self contained solution, not have a lot of helpers, I'll keep working and if I get anywhere the idea is to put the code up on my site anyway. Thanks for all the help so far.

http://www.element-games.com/palodequeso

Share this post


Link to post
Share on other sites
A quick heads up, I feel like an amature, however I forgot that classes in c++ do not inherent the constructors, which I forgot to re-write. So I'm going back through and adding in all of the right constructors, however, when i tested this out before when it wasn't in my engine yet, it seemed to be allocating the right memory. Who knows.

Share this post


Link to post
Share on other sites
The final verdict seems to be, to create three separate implementations without using inheritance but keeping the templates.

so now it will be

template <class Type, int size> class SquareMatrix{ /* stuff */ }
template <class Type, int size> class ColumnVector{ /* stuff */ }
template <class Type> class Transformation{ /* stuff */ }

thoughts?

Share this post


Link to post
Share on other sites
Quote:
Original post by Enalis
Man, I was hoping to have a nice self contained solution, not have a lot of helpers, I'll keep working and if I get anywhere the idea is to put the code up on my site anyway. Thanks for all the help so far.

http://www.element-games.com/palodequeso


Helpers often improve encapsulation. The natural C++ unit of "containment" for "solutions" is the translation unit, not the class.

Share this post


Link to post
Share on other sites

This topic is 3583 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this