Template Implicit function overload Function overload double ssqqdouble
Template Implicit function overload
Function overload double ssqq(double & a, double & b) { return(a*b); } float ssqq(float & a, float & b) {return(a*b); } main() { int na=3, nb=-5; float ra=2. 1, rb=-3. 4; double da=4. 7, db=-5. 6; cout << "integer : " << ssqq(na, nb) << "n"; cout << "float : " << ssqq(ra, rb) << "n"; cout << "double : " << ssqq(da, db) << "n"; system("pause"); return(0); } int ssqq(int & a, int & b) {return(a*b); }
template <class TYPE 1> TYPE 1 ssqq(TYPE 1 & a, TYPE 1 & b) { return (TYPE 1)(a*b); } main() { int na=3, nb=-5; float ra=2. 1, rb=-3. 4; double da=4. 7, db=-5. 6; cout << "integer : " << ssqq(na, nb) << "n"; cout << "float : " << ssqq(ra, rb) << "n"; cout << "double : " << ssqq(da, db) << "n"; system("pause"); return(0); } template <class csymbol>. . or template <typename tsymbol> class can be used for both class and variable type, but type name only refers to variable types
Function template with two types template <class TYPE 1, class TYPE 2> double ssqq(TYPE 1 & a, TYPE 2 & b) { return (double)(a*b); } main() { int na=3, nb=-5; float ra=2. 1, rb=-3. 4; double da=4. 7, db=-5. 6; cout << "2 integer : " << ssqq(na, nb) << "n"; cout << "float * double : " << ssqq(ra, db) << "n"; cout << "double * float : " << ssqq(da, rb) << "n"; system("pause"); return(0); }
Template-function overload template <typename TYPE 1, typename TYPE 2> double ssqq(TYPE 1 & a, TYPE 2 & b) { return((double)(a*b)); } template <typename TYPE 3> TYPE 3 ssqq(TYPE 3 & a) { return((TYPE 3)(a*a)); } main() { int na=3, nb=-5; float ra=2. 1, rb=-3. 4; double da=4. 7, db=-5. 6; cout << "2 integer : " << ssqq(na, nb) << "n"; cout << "float & integer : " << ssqq(ra, nb) << "n"; cout << "float & double : " << ssqq(rb, db) << "n"; cout << "1 integer : " << ssqq(na) << "n"; cout << "1 float : " << ssqq(ra) << "n"; cout << "1 double: " << ssqq(da) << "n";
Template class template <typename XTYPE> class position { XTYPE x, y, z; public: position(){}; position(XTYPE px, XTYPE py, XTYPE pz) { x = px; y=py; z=pz; } position(position<XTYPE> & r) {x=r. x; y=r. y; z=r. z; } //member functions XTYPE r() {return (XTYPE)(sqrt((double)(x*x+y*y+z*z))); } void setx(XTYPE rx){ x=rx; } void sety(XTYPE ry){ y=ry; } void setz(XTYPE rz){ z=rz; } XTYPE getx() { return(x); } XTYPE gety() { return(y); } XTYPE getz() { return(z); } XTYPE phi(); XTYPE theta(); void print(); };
Member function of template class template <class XTYPE> void position<XTYPE>: : print() { printf("x = %lf y = %lf z = %lfn", (double)x, (double)y, (double)z); } template <class XTYPE> XTYPE position<XTYPE>: : theta() { return( (XTYPE) acos(z/this->r())); } template <class XTYPE> XTYPE position<XTYPE>: : phi() { return( (XTYPE) atan 2(this->y, this->x) ); }
Using template class position<float> r(3. 0 F, 4. 0 F, 5. 0 F); r. print(); r. setx(3. 0); r. print(); printf("r=%f phi=%f theta=%fn", r. r(), 180. 0 F*r. phi()/My. Pi, 180. 0 F*r. theta()/My. Pi); position<double> ra[5]; // declare a position array for (i=0; i<5; i++) { ra[i]. setx(11. 0 + (double)i); ra[i]. sety(20. 0 + (double)i); ra[i]. setz(30. 0 + (double)i); }
Complex class Headfile: Declare: #include <complex> using namespace std; complex<double> ca, cb(1. 2, 6. 1); ca = complex<double>(2. 4, 5. 3);
Complex functions cout << "ca = " << ca << "n"; cout <<" real = " << ca. real() << "n"; cout <<" imag = " << ca. imag() << "n"; cout << "cb = " << cb << "n"; cout << "ca+cb = " << (ca+cb) << "n"; cout << "ca*cb = " << ca*cb << "n"; cout << ca << "conjugate = "<< conj(ca) << "n"; cout << "exp(ca) = " << exp(ca) << "n"; cout << "abs(ca) = " << abs(ca) << "n";
complex array complex<double> cc[4]; cc[0] = ca = complex<double>(0. 0, 1. 0); for (i=1; i<4; i++) cc[i] = cc[i-1] * ca; for (i=0; i<4; i++) cout << i << " : " << cc[i] << "n";
Practice Using Newton’s method to solve a root for a polynomial. Write the polynomial in a form of template class to allow complex coefficients. dx = f(x) / df(x); x = x – dx; All these variables will be double or complex numbers.
template <class XT> class polynomial { }; template <class XTYPE> class polynomial { int n; XTYPE *a; public: polynomial(int); //constructor polynomial(int, XTYPE *); //member functions XTYPE f (const XTYPE) const; XTYPE df(const XTYPE) const; void print() const; void coef(XTYPE *); inline void coef(int n, XTYPE x) {a[n] = x; } }; // end of class definition
constructor template <class XTYPE> polynomial<XTYPE>: : polynomial<XTYPE> (int nn, XTYPE *c) { int i; n = nn; a = new XTYPE[n+1]; if (a==NULL) n=0; else { for (i=0; i <= n; i++) a[i] = c[i]; } }
I/O format for complex number complex <double> a(1. 0, 2. 0); cout << a << “n” Output 結果: (1, 2) complex<double> b; cin >> b; 輸入格式為: (1. 0, 2. 0)
練習二. 將 Matrix class 加上 template for double and complex<double> typedef complex<double> CMPLX; // short-hand for complex<double> template <class XT> class Matrix { protected: XT *xpt; int nrow, ncol; public: . . }; // constructor, member function and frieds.
Constructors Matrix<XT>(){; } Matrix<XT>(const int, const int); Matrix<XT>(const Matrix<XT> &); Matrix<XT>(int, int , XT*); ~Matrix<XT>() { this->nrow = this->ncol = 0; delete [] this->xpt; } XT is the symbol defined at the declaration of a class object. class Matrix<double> m 1(3, 4), m 2; class matrix<complex<double> > c 1, c 2;
Example of constructor code built outside the class template <class XT> Matrix<XT>: : Matrix<XT>(int n, int m, XT *ap) { int i; if ((n > 0) && (m > 0) ) { this->xpt = new XT [n*m]; if (this->xpt != NULL) { this->nrow = n; this->ncol = m; for (i=0; i<(n*m); i++) this->xpt[i] = ap[i]; } } }
Manipulation member functions inline int row() const { return this->nrow; } inline int col() const { return this->ncol; } inline int dim() const { return (this->nrow * this->ncol) ; } inline int CV(const int i, const int j) const { return(ncol*i + j); } inline XT get(const int i, const int j) const { return this->xpt[CV(i, j)]; } inline void set(const int i, const int j, XT xx) { this->xpt[CV(i, j)] = xx; } inline XT get(const int i) const { return this->xpt[i]; } inline void set(const int i, XT xx) { this->xpt[i] = xx; } Matrix<XT> getcol(int) const; // get a column form the matrix Matrix<XT> getrow(int) const; // get a row from the matrix
Example of Member function built outside the class template <class XT> Matrix<XT>: : getcol(int nr) const { int i; Matrix<XT> colv(this->nrow, 1); for (i=0; i < this->nrow; i++) colv. xpt[i] = this->get(i, nr); return colv; }
Utility member functions double norm() const; // remain double inline double abs() const {return sqrt(this->norm()); } Matrix<XT> transport() const; Matrix<XT> adjoint() const; // for complex -- transport and conjugate adjoint: 共軛轉置矩陣 程式中若須要區分 double 和 complex, 可用 sizeof(XT). 當 sizeof (XT) <= 8 adjoint = transport In code norm: 先把 xx cast 轉成 complex, 取共軛再相乘, 乘完再取 real. template <class XT> double Matrix<XT>: : norm() XT xx; xx = this->xpt[i]; sum = sum + (conj((CMPLX)xx) * xx). real(); 不然就必須把 Matrix<double> 和 Matrix<CMPLX> 分開寫兩個程式.
Unary operator Declaration inside class: Matrix<XT> &operator= (const Matrix<XT>); Matrix<XT> &operator+=(const Matrix<XT>); Matrix<XT> &operator-=(const Matrix<XT>); Code outside the class: template <class XT> Matrix<XT> &Matrix<XT>: : operator+=(const Matrix<XT> m 2) { int i; if ((this->ncol==m 2. ncol) && (this->nrow==m 2. nrow)) for (i=0; i<this->dim(); i++) this->xpt[i] += m 2. xpt[i]; else { this->ncol = this->nrow = 0; delete [] this->xpt; } return *this; } // the code is same for both double and complex.
Template defined friend functions template <class TT> friend ostream &operator<<(ostream &, Matrix<TT>); template <class TT> friend Matrix<TT> operator+(Matrix<TT>, Matrix<double>); template <class TT> friend Matrix<CMPLX> operator+(Matrix<TT>, Matrix<CMPLX>); template <class TT> friend Matrix<TT> operator-(Matrix<TT>, Matrix<double>); template <class TT> friend Matrix<CMPLX> operator-(Matrix<TT>, Matrix<CMPLX>); template <class TT> friend Matrix<TT> operator*(double, Matrix<TT>); template <class TT> friend Matrix<CMPLX> operator*(CMPLX, Matrix<TT>); template <class TT> friend Matrix<TT> operator*(Matrix<TT>, double); template <class TT> friend Matrix<CMPLX> operator*(Matrix<TT>, CMPLX); template <class TT> friend Matrix<TT> operator*(Matrix<TT>, Matrix<double>); template <class TT> friend Matrix<CMPLX> operator*(Matrix<TT>, Matrix<CMPLX>); 每一個用任何 class 或 變數 取代 TT 所得的函數, 都被當作是 class Matrix 的 friend function.
Template friend operator built outside the class template <class XT> Matrix<CMPLX> operator+(Matrix<XT> m 1, Matrix<CMPLX> m 2) { int i; Matrix<CMPLX> m 3; if ((m 1. nrow == m 2. nrow) && (m 1. ncol == m 2. ncol)) { m 3 = m 1; for (i=0; i<m 3. dim(); i++) m 3. xpt[i] += m 2. xpt[i]; } else { m 3. ~Matrix<CMPLX>(); } return m 3; }
Exmaple of program using Matrix<CMPLX> class #include <cstdlib> #include <iostream> #include "ytlu. Matrix 2. h“ // CMPLX = complex<double> using namespace std; int main() { int n=3, m=4, i; CMPLX xx[12]; for (i=0; i<12; i++) xx[i] = CMPLX((double)i, (double)i*0. 5 ); Matrix<CMPLX> a 1(n, m, xx), a 3, a 4; Matrix<CMPLX> a 2(m, n, xx); cout << " a 1 = " << a 1 ; cout << " 2 nd COlumn of a 1 " << a 1. getcol(1); cout << " 2 nd row of a 1 " << a 1. getrow(1); cout << " a 2 = " << a 2; a 3 = a 4 = a 1; cout << "a 1 = " << a 1 << "a 3 = " << a 3 << "a 4 = " << a 4; cout << "a 1 + a 3 + a 4 = " << (a 1+a 3+a 4); cout << "a 1 * (1 i) " << a 1 * CMPLX(0. 0, 1. 0); cout << "a 1 * 2. 0 " << a 1 * 2. 0; cout << "(1 i) * a 1 *2 " << CMPLX(0. 0, 1. 0)*a 1*2. 0; cout << "a 1 * a 2" << a 1 * a 2; system("pause"); return 0; }
Example of using Matrix<double> #include <cstdlib> #include "ytlu. Matrix 2. h“ // typedef complex<double> CMPLX using namespace std; int main() { int n=3, m=4; double xx[12] = { 1. , 2. , 3. , 4. , 5. , 6. , 7. , 8. , 9. , 10. , 11. , 12. }; Matrix<double> a 1(3, 4, xx), a 3, a 4; Matrix<double> a 2(4, 3, xx); cout << " a 1 = " << a 1 ; cout << " 2 nd Column of a 1 " << a 1. getcol(1); cout << " 2 nd row of a 1 " << a 1. getrow(1); cout << " a 2 = " << a 2; a 3 = a 4 = a 1; cout << "a 1 = " << a 1 << "a 3 = " << a 3 << "a 4 = " << a 4; cout << "a 1 + a 3 + a 4 = " << (a 1+a 3+a 4); cout << "a 3 - a 4 " << (a 3 -a 4); cout << "a 1 - a 3 -a 4 " << (a 1 -a 3 -a 4); cout << "a 1 * (1 i) " << a 1 * CMPLX(0. 0, 1. 0); cout << "a 1 * 2. 0 " << a 1 * 2. 0; cout << "(1 i) * a 1 *2 " << CMPLX(0. 0, 1. 0)*a 1*2. 0; cout << "a 1 * a 2" << a 1 * a 2; cout << "(1 i)*a 1 *a 2" << CMPLX(0. 0, 1. 0)*a 1*a 2; system("pause"); return 0; }
- Slides: 26