Thread overview
Another template strangeness
Sep 23, 2002
Iliya Peregoudov
Sep 24, 2002
Walter
Sep 24, 2002
Iliya Peregoudov
Sep 24, 2002
Mark Evans
Sep 25, 2002
Walter
Sep 25, 2002
Walter
Sep 25, 2002
Iliya Peregoudov
Sep 25, 2002
Walter
September 23, 2002
The idea of the following sample code is simple.  First, we keep track
of matrix features (square, diagonal, column, or row) as a type.
Second,  we want the type to divert minimally in the process of matrix
multiplication.  Specifically, this code tries to differentiate
multiplication of column matrix by row matrix into two cases:

1) when column matrix and row matrix are the same size the result is
   square matrix,
2) otherwise the result is general (rectangular) matrix.

This code compiles cleanly by g++ 2.96 and KAI C++ 4.0.  dmc gives
numerious errors about multiple non-identical declarations of
operator*.

/* matrix4.cpp */
#include <iostream.h>

template <class T, int n> class ColMatrix;
template <class T, int m> class RowMatrix;

template <class T, int n, int m>
class Matrix {
protected:
   T v[n][m];
public:
   template <class TT, int nn, int mm>
   friend Matrix<TT,nn,mm> operator*(const ColMatrix<TT,nn> &, const RowMatrix<TT,mm> &);
};

template <class T, int n>
class SquareMatrix: public Matrix<T,n,n> {
public:
   template <class TT, int nn>
   friend SquareMatrix<TT,nn> operator*(const ColMatrix<TT,nn> &, const RowMatrix<TT,nn> &);
};

template <class T, int n>
class ColMatrix: public Matrix<T,n,1> {
public:
   template <class TT, int nn, int mm>
   friend Matrix<TT,nn,mm> operator*(const ColMatrix<TT,nn> &, const RowMatrix<TT,mm> &);
   template <class TT, int nn>
   friend SquareMatrix<TT,nn> operator*(const ColMatrix<TT,nn> &, const RowMatrix<TT,nn> &);
};

template <class T, int m>
class RowMatrix: public Matrix<T,1,m> {
public:
   template <class TT, int nn, int mm>
   friend Matrix<TT,nn,mm> operator*(const ColMatrix<TT,nn> &, const RowMatrix<TT,mm> &);
   template <class TT, int nn>
   friend SquareMatrix<TT,nn> operator*(const ColMatrix<TT,nn> &, const RowMatrix<TT,nn> &);
};

template <class TT, int nn, int mm>
Matrix<TT,nn,mm> operator*(const ColMatrix<TT,nn> &a, const RowMatrix<TT,mm> &b)
{
   Matrix<TT,nn,mm> r;
   for (int i = 0; i < nn; ++i)
      for (int j = 0; j < mm; ++j)
         r.v[i][j] = a.v[i][0]*b.v[0][j];
   return r;
}

template <class TT, int nn>
SquareMatrix<TT,nn> operator*(const ColMatrix<TT,nn> &a, const RowMatrix<TT,nn> &b)
{
   SquareMatrix<TT,nn> r;
   for (int i = 0; i < nn; ++i)
      for (int j = 0; j < nn; ++j)
         r.v[i][j] = a.v[i][0]*b.v[0][j];
   return r;
}

int main()
{
   ColMatrix<int,2> m1;
   RowMatrix<int,2> m2;
   m1*m2;  // should give SquareMatrix

   return 0;
}

September 24, 2002
The fix is posted now. -Walter


September 24, 2002
Walter wrote:
> The fix is posted now. -Walter

Ok, but if we change main() in the previous example to

int main()
{
   ColMatrix<int,2> m1;
   RowMatrix<int,2> m2;
   RowMatrix<int,3> m3;
   m1*m2;  // should give SquareMatrix
   m1*m3;  // should give Matrix

   return 0;
}

compiler say:

   m1*m3;  // should give Matrix
        ^
matrix4.cpp(66) : Error: need explicit cast for function parameter 1 to get
from: ColMatrix<int ,2>
to  : const ColMatrix<int ,3>

It seems that compiler doesn't see operator*() that return rectangular matrix.  [Why does it want to cast the first operator*() argument?  The second one should be the choice of the very same priority...]

September 24, 2002
Just a thank you to Iliya for exploring these matters, and Walter for fixing them!

Hey Walter be sure to put even the most minor patches on c++-announce...I check it all the time...I'd like to know what goes on between X.YY.ZZ.01 and X.YY.ZZ.02.

Mark


September 25, 2002
>matrix4.cpp(66) : Error: need explicit cast for function parameter 1 to get
>from: ColMatrix<int ,2>
>to  : const ColMatrix<int ,3>

The fix for that is posted now too <g>.


September 25, 2002
"Mark Evans" <Mark_member@pathlink.com> wrote in message news:amqq01$u2i$1@digitaldaemon.com...
> Just a thank you to Iliya for exploring these matters, and Walter for
fixing
> them!

Welcs!

> Hey Walter be sure to put even the most minor patches on c++-announce...I
check
> it all the time...I'd like to know what goes on between X.YY.ZZ.01 and X.YY.ZZ.02.

Done!


September 25, 2002
> The fix for that is posted now too <g>.
>

It rocks! Excellent work, Walter!

P.S.: I'm really amazed by the how fast all of this was fixed out. Looks more like a magic!

September 25, 2002
"Iliya Peregoudov" <iliyap@mail.ru> wrote in message news:3D91F652.3060300@mail.ru...
> > The fix for that is posted now too <g>.
> It rocks! Excellent work, Walter!
> P.S.: I'm really amazed by the how fast all of this was fixed out.
> Looks more like a magic!

What was wrong was the template partial ordering code was well tested for type arguments, but apparently none of the stlport tests tested it with value arguments. So once I figured out what was going wrong, it wasn't too hard to fix.