templatized matrix system with inheritance
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.
Maybe the problem is that unexpected second float argument? Why is it there? ;)
BASE::GRAPHICS::Graphics::Color(BASE::MATH::Matrix<float, 3, 1>, float)
BASE::GRAPHICS::Graphics::Color(BASE::MATH::Matrix<float, 3, 1>, float)
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.
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.
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.
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+=)?
Quote:Original post by EnalisThat makes no sense to me. I don't suppose you're able to remember where you read that?
Mawww, I had them in as typedefs, but then I read typedef's for templates are bad.
However let me make this clear: "#defines instead of typedefs are bad".
There I've said it.
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?
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
Popular Topics
Advertisement