Thanks for the help. Using your suggestions and quite a few hours of
playing around, I have gotten my program to the point where none of
the obvious errors are being flagged in the template class, but
instead in the driver class (which I know has no errors). Sorry for
the huge post but I am including first the errors, then the template
class and finally the driver. Thakns again for any help folks.
Zenon
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
ex5.cpp:
Error E2285 ex5.cpp 141: Could not find a match for
'matrix<complex<double> >:
perator =(complex<double>)' in function main()
Error E2285 ex5.cpp 142: Could not find a match for
'matrix<complex<double> >:
perator =(complex<double>)' in function main()
Error E2285 ex5.cpp 143: Could not find a match for
'matrix<complex<double> >:
perator =(complex<double>)' in function main()
Error E2285 ex5.cpp 144: Could not find a match for
'matrix<complex<double> >:
perator =(complex<double>)' in function main()
Error E2285 ex5.cpp 176: Could not find a match for
'complex<double>:
perator =
<X>(matrix<complex<double> >)' in function main()
Error E2034 ex5.cpp 185: Cannot convert 'matrix<double>' to 'double'
in function
main()
Error E2034 ex5.cpp 242: Cannot convert 'const matrix<double>' to
'matrix<Type>'
in function main()
Error E2342 ex5.cpp 242: Type mismatch in parameter 'object' (wanted
'const matr
ix<Type> &', got 'matrix<double>') in function main()
Error E2102 ex5.cpp 248: Cannot use template 'yp' without specifying
specializat
ion parameters in function main()
Error E2102 ex5.cpp 250: Cannot use template 'yp' without specifying
specializat
ion parameters in function main()
Error E2102 ex5.cpp 251: Cannot use template 'yp' without specifying
specializat
ion parameters in function main()
Error E2357 matrix.h 318: Reference initialized with 'double', needs
lvalue of t
ype 'matrix<double>' in function matrix<double>::lookup(int,int)
Warning W8004 matrix.h 319: 'linear_index' is assigned a value that is
never use
d in function matrix<double>::lookup(int,int)
Error E2357 matrix.h 326: Reference initialized with 'const double',
needs lvalu
e of type 'matrix<double>' in function matrix<double>::lookup(int,int)
const
Warning W8004 matrix.h 327: 'linear_index' is assigned a value that is
never use
d in function matrix<double>::lookup(int,int) const
Error E2357 matrix.h 326: Reference initialized with 'const
complex<double>', ne
eds lvalue of type 'matrix said:
Warning W8004 matrix.h 327: 'linear_index' is assigned a value that is
never use
d in function matrix<complex<double> >::lookup(int,int) const
*** 14 errors in Compile ***
// Template class
#include <iostream>
#include <string>
#include <vector>
template <class Type>
class matrix
{
private:
std::vector<Type> _data ;
public:
class iterator
{
int _current_row ;
int _current_col ;
matrix<Type>& _object ;
public:
// Iterator constructor implementation
iterator (matrix<Type>& object)
: _object (object), _current_row (0), _current_col (0)
{}
~iterator ()
{}
iterator operator++ (int dummy)
{
_current_col++ ;
if (_current_col >= _object. cols())
{
_current_row++ ;
_current_col = 0 ;
}
return *this ;
}
static matrix<Type> dummy ;
matrix<Type>& operator* ()
{
if (*this)
{
return _object (_current_row, _current_col) ;
}
else
{
return dummy ;
}
}
operator bool () const
{
if (_current_row >= _object. rows())
{
return false ;
}
else
{
return true ;
}
}
} ;
//***************************************************************************************
template <class Type>
class const_iterator
{
int _current_row ;
int _current_col ;
const matrix<Type>& _object ;
public:
const_iterator (const matrix<Type>& object)
: _object (object), _current_row (0), _current_col (0)
{}
~const_iterator ()
{}
const_iterator operator++ (int dummy)
{
_current_col++ ;
if (_current_col >= _object. cols())
{
_current_row++ ;
_current_col = 0 ;
}
return *this ;
}
static matrix<Type> dummy ;
const matrix<Type>& operator* () const
{
if (*this)
{
return _object (_current_row, _current_col) ;
}
else
{
return dummy ;
}
}
operator bool () const
{
if (_current_row >= _object. rows())
{
return false ;
}
else
{
return true ;
}
}
} ;
//***************************************************************************************
private:
int _nrows ;
int _ncols ;
public:
matrix (int rows=1, int cols=1) ;
matrix (const matrix<Type>& rhs) ;
~matrix () {};
matrix& operator=(const matrix<Type>& rhs) ;
matrix& lookup (int row, int col) ;
const matrix& lookup (int row, int col) const ;
matrix& operator() (int row, int col)
{
return lookup (row, col) ;
}
const matrix& operator() (int row, int col) const
{
return lookup (row, col) ;
}
int rows () const
{
return _nrows ;
}
int cols () const
{
return _ncols ;
}
bool add (const matrix<Type>& rhs, matrix<Type>& result) const ;
matrix operator+ (const matrix<Type>& rhs) const ;
void put (std:
stream& os) const ;
void get (std::istream& is) ;
friend class iterator ;
} ; // end matrix
//***************************************************************************************
// Matrix constructor implementation
template <class Type>
matrix<Type>::matrix (int rows, int cols)
: _data (rows * cols), _nrows (rows), _ncols (cols)
{ }
//
template <class Type>
matrix<Type>::matrix (const matrix<Type>& rhs)
: _data (rhs._data), _nrows(rhs._nrows), _ncols(rhs._ncols)
{ }
// Matrix operator= implementation
template <class Type>
matrix<Type>& matrix<Type>:
perator= (const matrix<Type>& rhs)
{
if (this != &rhs)
{
_data = rhs. _data ;
_nrows = rhs. _nrows ;
_ncols = rhs. _ncols ;
}
return *this ;
}
// Matrix lookup implementation
template <class Type>
matrix<Type>& matrix<Type>::lookup (int row, int col)
{
int linear_index = row * _ncols + col ;
return _data [linear_index] ;
}
// Overloaded matrix lookup implementation
template <class Type>
const matrix<Type>& matrix<Type>::lookup (int row, int col) const
{
int linear_index = row * _ncols + col ;
return _data [linear_index] ;
}
// Matrix Put implementation
template <class Type>
void matrix<Type>:
ut (std:
stream& os) const
{
os << _nrows << " " << _ncols << endl ;
for (int rix=0; rix<_nrows; rix++)
{
for (int cix=0; cix<_ncols; cix++)
{
os << lookup (rix, cix) << " " ;
}
os << endl ;
}
}
// Matrix get implementation
template <class Type>
void matrix<Type>::get (std::istream& is)
{
is >> _nrows >> _ncols ;
_data.resize (_nrows * _ncols) ;
for (int rix=0; rix<_nrows; rix++)
{
for (int cix=0; cix<_ncols; cix++)
{
is >> lookup (rix, cix) ;
}
}
}
// Matrix add implementation
template <class Type>
bool matrix<Type>::add (const matrix<Type>& rhs, matrix<Type>&
result) const
{
if ((_nrows != rhs._nrows) || (_ncols != rhs._ncols))
{
return false ;
}
result._data.resize (_nrows * _ncols) ;
for (int rix=0; rix<_nrows; rix++)
{
for (int cix=0; cix<_ncols; cix++)
{
result.lookup (rix, cix) = lookup (rix, cix) + rhs.lookup (rix,
cix) ;
}
}
return true ;
}
// Matrix operator + implementation
template <class Type>
matrix<Type> matrix<Type>:
perator+ (const matrix<Type>& rhs) const
{
matrix<Type> result (_nrows, _ncols) ;
add (rhs, result) ;
return result ;
}
//***************************************************************************************
inline
template <class Type>
std:
stream& operator<< (std:
stream& os, const matrix<Type>& rhs)
{
rhs. put (os) ;
return os ;
}
inline
template <class Type>
std::istream& operator>> (std::istream& is, matrix<Type>& rhs)
{
rhs. get (is) ;
return is ;
}
// Driver
// ===========================================================================
//
// File: ex5.C
//
// Description:
//
// This program is the "matrix" test driver for exercise 5. It
creates
// several "matrix<double>" objects (some constant), copies them,and tries
// the new operators (and verifies the old functions too). It also
creates
// a "matrix<complex<double> >" object and tries basic
functionality.
//
// Verification is manual - that is, you run the program and
// inspect the output.
//
//
//
// ===========================================================================
//
#include <fstream>
#include <iostream>
#include <complex>
#include "matrix.h"
using namespace std ;
//
// supporting function - this will be used in part 2 of the test
//
template <class T>
void print_matrix (ostream& os, const matrix<T>& data)
{
int nrows = data.rows() ;
int ncols = data.cols() ;
os << nrows << " rows by " << ncols << "columns" << endl ;
for (int rix=0; rix<nrows; rix++)
{
for (int cix=0; cix<ncols; cix++)
{
if (cix > 0)
{
os << ", " ;
}
os << data (rix, cix) ;
}
os << endl ;
}
}
int main ()
{
ostream& os = cout ;
// --------------------------------------------------------------------
//
// Part 1 - test basic capabilities:
//
// constructor
// destructor
// operator ()
// operator <<
// iterator constructor
// iterator operator++
// iterator operator*
// iterator operator bool
//
// Create a matrix, fill it with data, and print it out.
//
// This test executes inside a block so that the "matrix"
// destructor is called at the end of part 1 testing.
//
// --------------------------------------------------------------------
{
os << "Matrix Testing - Part 1" << endl ;
os << "-----------------------" << endl ;
matrix<double> X (2, 3) ;
// operator ()
X (0, 0) = 100.0 ;
X (0, 1) = 100.1 ;
X (0, 2) = 100.2 ;
X (1, 0) = 101.0 ;
X (1, 1) = 101.1 ;
X (1, 2) = 101.2 ;
// operator << and size
int nrows = X.rows() ;
int ncols = X.cols() ;
os << "matrix X (" << nrows << " rows by " << ncols
<< " colmns) = " << endl ;
os << X ;
//
// repeat the output operation using iterator
// (and change one matrix entry to verify that that works)
//
X (1, 1) = 201.1 ;
matrix<double>::iterator xp (X) ;
double value ;
os << endl ;
os << "Using iterator" << endl ;
while (xp) // operator bool
{
os << *xp << endl ;
xp++ ;
}
}
// --------------------------------------------------------------------
//
// Part 2 - Multiple objects:
//
// Now that we have confidence in the basic functionality of our
// matrix, let's create two of them and make sure there's no problem
// with that.
//
// --------------------------------------------------------------------
{
os << endl ;
os << endl ;
os << "Matrix Testing - Part 2" << endl ;
os << "-----------------------" << endl ;
matrix<complex<double> > Y (2, 2) ;
Y (0, 0) = complex<double> (300.0, 1) ;
Y (0, 1) = complex<double> (300.1, 0) ;
Y (1, 0) = complex<double> (301.0, -1) ;
Y (1, 1) = complex<double> (301.1, 0) ;
matrix<double> Z (3, 3) ;
Z (0, 0) = 400.0 ;
Z (0, 1) = 400.1 ;
Z (0, 2) = 400.2 ;
Z (1, 0) = 401.0 ;
Z (1, 1) = 401.1 ;
Z (1, 2) = 401.2 ;
Z (2, 0) = 402.0 ;
Z (2, 1) = 402.1 ;
Z (2, 2) = 402.2 ;
os << "Y = " << endl ;
print_matrix (os, Y) ;
os << endl ;
os << "Z = " << endl ;
print_matrix (os, Z) ;
//
// multiple iterators
//
matrix<complex<double> >::iterator yp (Y) ;
complex<double> yvalue ;
for (int yix=0; yix<2; yix++)
{
yp++ ;
}
yvalue = *yp ;
matrix<double>::iterator zp (Z) ;
double zvalue ;
for (int zix=0; zix<6; zix++)
{
zp++ ;
}
zvalue = *zp ;
os << endl ;
os << "*yp = " << yvalue << endl ;
os << "*zp = " << zvalue << endl ;
}
// --------------------------------------------------------------------
//
// Part 3 - Check copy operations and more of the const.
//
// --------------------------------------------------------------------
{
os << endl ;
os << endl ;
os << "Matrix Testing - Part 3" << endl ;
os << "-----------------------" << endl ;
//
// make a copy of a matrix using assignment, and using a copy
// constructor.
//
matrix<double> X (3, 2) ;
// operator ()
X (0, 0) = 500.0 ;
X (0, 1) = 500.1 ;
X (1, 0) = 501.0 ;
X (1, 1) = 501.1 ;
X (2, 0) = 502.0 ;
X (2, 1) = 502.1 ;
const matrix<double> Y = X ; // copy constructor
matrix<double> Z ; // default constructor
Z = X ; // assignment
X (0, 0) = 100 ; // "destroy" X to ensure that
X (0, 1) = 100 ; // Y and Z are true copies
X (1, 0) = 100 ;
X (1, 1) = 100 ;
X (2, 0) = 100 ;
X (2, 1) = 100 ;
Z (0, 0) = 700.0 ;
os << "Y = " << endl ;
os << Y ;
os << endl ;
os << endl ;
//
// repeat the output operation using const_iterator
//
matrix<double>::const_iterator yp (Y) ;
double value ;
os << endl ;
os << "Using const_iterator" << endl ;
while (yp) // operator bool
{
os << *yp << endl ;
yp++ ;
}
os << "Z = " << endl ;
os << Z ;
os << endl ;
os << endl ;
matrix<double> S (Y+Z) ;
matrix<double> T (Z+Y) ;
os << "S = " << endl ;
os << S ;
os << endl ;
os << endl ;
os << "T = " << endl ;
os << T ;
os << endl ;
os << endl ;
// check basic I/O
matrix<double> R ;
{
ofstream otmp ("temp.tmp") ;
otmp << S ;
otmp << endl ;
}
{
ifstream itmp ("temp.tmp") ;
itmp >> R ;
}
os << "R = " << endl ;
os << R ;
os << endl ;
os << endl ;
}
} // end exercise 3 test driver