templatized matrix system with inheritance

Started by
13 comments, last by Zahlman 16 years, 2 months ago
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.
Douglas Eugene Reisinger II
Projects/Profile Site
Advertisement
Maybe the problem is that unexpected second float argument? Why is it there? ;)

BASE::GRAPHICS::Graphics::Color(BASE::MATH::Matrix<float, 3, 1>, float)
Another thing is that you should use typedefs instead of #defines to define your new types.
Tchou kanaky ! tchou !
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.
Douglas Eugene Reisinger II
Projects/Profile Site
If you're passing a parameter by value you need to match the exact type. You want to pass them by const reference, reference or pointer to fix it.
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.
When General Patton died after World War 2 he went to the gates of Heaven to talk to St. Peter. The first thing he asked is if there were any Marines in heaven. St. Peter told him no, Marines are too rowdy for heaven. He then asked why Patton wanted to know. Patton told him he was sick of the Marines overshadowing the Army because they did more with less and were all hard-core sons of bitches. St. Peter reassured him there were no Marines so Patton went into Heaven. As he was checking out his new home he rounded a corner and saw someone in Marine Dress Blues. He ran back to St. Peter and yelled "You lied to me! There are Marines in heaven!" St. Peter said "Who him? That's just God. He wishes he were a Marine."
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+=)?
Douglas Eugene Reisinger II
Projects/Profile Site
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.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
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?
Douglas Eugene Reisinger II
Projects/Profile Site
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 exampleT 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);

This topic is closed to new replies.

Advertisement