www.digitalmars.com Home | Search | C & C++ | D | DMDScript | News Groups | index | prev | next
Archives

D Programming
D
D.gnu
digitalmars.D
digitalmars.D.bugs
digitalmars.D.dtl
digitalmars.D.dwt
digitalmars.D.announce
digitalmars.D.learn
digitalmars.D.debugger

C/C++ Programming
c++
c++.announce
c++.atl
c++.beta
c++.chat
c++.command-line
c++.dos
c++.dos.16-bits
c++.dos.32-bits
c++.idde
c++.mfc
c++.rtl
c++.stl
c++.stl.hp
c++.stl.port
c++.stl.sgi
c++.stlsoft
c++.windows
c++.windows.16-bits
c++.windows.32-bits
c++.wxwindows

digitalmars.empire
digitalmars.DMDScript

c++ - Another template strangeness

↑ ↓ ← Iliya Peregoudov <iliyap mail.ru> writes:
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;
}
Sep 23 2002
↑ ↓ "Walter" <walter digitalmars.com> writes:
The fix is posted now. -Walter
Sep 24 2002
↑ ↓ Iliya Peregoudov <iliyap mail.ru> writes:
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...]
Sep 24 2002
Mark Evans <Mark_member pathlink.com> writes:
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
Sep 24 2002
↑ ↓ → "Walter" <walter digitalmars.com> writes:
"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

 them!

Welcs!
 Hey Walter be sure to put even the most minor patches on c++-announce...I

 it all the time...I'd like to know what goes on between X.YY.ZZ.01 and
 X.YY.ZZ.02.

Done!
Sep 24 2002
"Walter" <walter digitalmars.com> writes:
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>.
Sep 24 2002
↑ ↓ Iliya Peregoudov <iliyap mail.ru> writes:
 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!
Sep 25 2002
↑ ↓ → "Walter" <walter digitalmars.com> writes:
"Iliya Peregoudov" <iliyap mail.ru> wrote in message
news:3D91F652.3060300 mail.ru...
 The fix for that is posted now too <g>.

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.
Sep 25 2002